package com.alibaba.citrus.cr.order.open.api.facade.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.citrus.cr.common.annotation.FacadeInvoker;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.common.lock.RedisLock;
import com.alibaba.citrus.cr.common.log.ModuleEnum;
import com.alibaba.citrus.cr.common.util.ThreadPoolUtil;
import com.alibaba.citrus.cr.order.open.api.facade.common.until.CheckUtil;
import com.alibaba.citrus.cr.unified.inventory.facade.service.AllocateApplyOrderWriteServiceImpl;
import com.alibaba.citrus.cr.unified.inventory.functions.allocateApplyOrder.AllocateApplyOrderEntity;
import com.alibaba.citrus.cr.unified.inventory.functions.allocateApplyOrder.AllocateApplyOrderFactory;
import com.alibaba.citrus.cr.unified.inventory.repository.AllocateApplyOrderDetailReadRepository;
import com.alibaba.citrus.cr.unified.inventory.repository.AllocateApplyOrderDetailWriteRepository;
import com.alibaba.cz.base.tool.FeatureUtil;
import com.alibaba.cz.base.tool.Nullable;
import com.alibaba.cz.base.tool.feature.Features;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.cz.base.tool.log.model.OpLogModel;
import com.alibaba.cz.base.tool.log.model.OperatorType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.lattice2.epoch.middleware.mq.runtime.EpochMessageService;
import com.alibaba.lattice2.epoch.sdk.model.Result;
import com.alibaba.lattice2.epoch.user.dto.LoginUser;
import com.alibaba.lattice2.epoch.user.service.EpochLoginUserService;
import com.epoch.app.bcorder.contants.BcOrderConstants;
import com.epoch.app.bcorder.model.dto.QueryGoodsListUnifiedInventoryRequest;
import com.epoch.app.bcorder.model.dto.QueryGoodsListUnifiedInventoryResponse;
import com.epoch.app.bcorder.service.PlatformEnhanceService;
import com.epoch.app.crunifiedinventory.api.allocateapplyorderread.service.AllocateApplyOrderReadService;
import com.epoch.app.crunifiedinventory.api.allocateapplyorderwrite.service.AllocateApplyOrderWriteService;
import com.epoch.app.crunifiedinventory.contants.CrUnifiedInventoryConstants;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.dto.AllocateApplyOrderLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.dto.GetRequest;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.dto.UpdateFeaturesRequest;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.dto.LoadAllocateApplyOrderByCodeV2Request;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.model.AllocateApplyOrder;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorder.service.AllocateApplyOrderService;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.dto.AllocateApplyOrderDetailLoadListRequest;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.model.AllocateApplyOrderDetail;
import com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.service.AllocateApplyOrderDetailService;
import com.epoch.app.crunifiedinventory.dto.request.CancelAllocateApplyOrderRequest;
import com.epoch.app.crunifiedinventory.dto.request.QueryAllocateApplyOrderRequest;
import com.epoch.app.crunifiedinventory.dto.request.RejectAllocateApplyOrderRequest;
import com.epoch.app.crunifiedinventory.dto.response.AllocateApplyOrderDetailDTO;
import com.epoch.app.crunifiedinventory.dto.response.AllocateApplyOrderGoodsDetailDTO;
import com.epoch.app.crunifiedinventory.model.dto.*;
import com.epoch.app.crunifiedinventory.model.enums.AllocateApplyOrderOperationTypeEnum;
import com.epoch.app.crunifiedinventory.sdo.AllocateApplyOrderDetailSDO;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateApplyOrderStatusEnum;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.epoch.app.crunifiedinventory.sdo.enums.DocumentTypeEnum;
import com.epoch.app.crunifiedinventory.sdo.enums.TransportModeEnum;
import com.epoch.app.mninventorycenter.model.dto.DictionaryResponse;
import com.epoch.app.mninventorycenter.model.dto.WarehouseQueryRequest;
import com.epoch.app.mninventorycenter.model.dto.WarehouseQueryResponse;
import com.epoch.app.mninventorycenter.model.dto.*;
import com.epoch.app.mninventorycenter.service.MnInventoryCenterService;
import com.epoch.app.mninventorycenter.transferforecastorderwrite.service.TransferForecastOrderWriteService;
import com.google.common.collect.Sets;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.internal.util.EqualsUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@Primary
public class TransferForecastOrderWriteServiceImpl implements TransferForecastOrderWriteService{

    private static final String ALLOCATE_APPLY_ORDER_TOPIC = "CZ_APPLY_ALLOCATE_ORDER_V2";
    Log log = com.alibaba.cz.base.tool.log.Log.getLogger(AllocateApplyOrderWriteServiceImpl.class);

    @Resource
    private PlatformEnhanceService platformEnhanceService;
    @Resource
    private AllocateApplyOrderWriteService allocateApplyOrderWriteService;

    @Resource
    private AllocateApplyOrderDetailWriteRepository allocateApplyOrderDetailWriteRepository;

    @Resource
    private AllocateApplyOrderDetailReadRepository allocateApplyOrderDetailReadRepository;

    @Resource
    @Qualifier("allocateApplyOrderReadServiceImpl")
    private AllocateApplyOrderReadService allocateApplyOrderReadService;

    @Resource
    private MnInventoryCenterService mnInventoryCenterService;

    @Resource
    private AllocateApplyOrderService allocateApplyOrderService;
    @Resource
    private AllocateApplyOrderDetailService allocateApplyOrderDetailService;

    @Resource
    private EpochLoginUserService epochLoginUserService;

    @Resource
    private EpochMessageService messageService;

    private static final String FROM_SYS_GROUP = "fromSys";
    private static final String BUSINESS_TYPE_GROUP = "businessType";
    //第三次创建预报单标记，不需要登录人信息校验
    private static final String FROM_THIRD_PARTY="mn_inventory_api";
    private static final String UPDATE_FEATURES = "transfer_forecast_order_updateFeatures";
    private static final String MN_APP = "mn_app";

    private static final String DATE_FORMAT = "yyyy-MM-dd";


    @Override
    @FacadeInvoker(value = "调拨预报单创建")
    public Result<TransferForecastOrderCreateResponse> createTransferForecastOrder(
            TransferForecastOrderCreateRequest transferForecastOrderCreateRequest) {
        log.info("createTransferForecastOrder_request:{}",JSON.toJSONString(transferForecastOrderCreateRequest));

        String message = checkCreateTransferForecastOrder(transferForecastOrderCreateRequest);
        if (message !=null) {
            return Result.fail("10000",message);
        }
        String key =transferForecastOrderCreateRequest.getBusinessType()+"_"
                +transferForecastOrderCreateRequest.getFromSys()+"_"
                +transferForecastOrderCreateRequest.getRequestId()+"_"
                +transferForecastOrderCreateRequest.getThirdAllocateApplyOrderId();
        //请求幂等
        try (RedisLock lock = new RedisLock(BcOrderConstants.REDIS_CACHE_CODE(),
                "createTransferForecastOrder_" + key,
                5000,10000)){
            if (!lock.lock()){
                return Result.fail("10009","不能重复提交");
            }
            Result<List<AllocateApplyOrder>> idempotentResult = allocateApplyOrderService.loadAllocateApplyOrderList(AllocateApplyOrderLoadListRequest
                    .newAllocateApplyOrderLoadListRequestBuilder()
                    .businessType(transferForecastOrderCreateRequest.getBusinessType())
                    .fromSys(transferForecastOrderCreateRequest.getFromSys())
                    .thirdAllocateApplyOrderId(transferForecastOrderCreateRequest.getThirdAllocateApplyOrderId()).build());
            if (CollectionUtils.isNotEmpty(idempotentResult.getResult())) {
                return Result.fail("10002","单据已存在，请勿重复请求");
            }
            List<String> scItemCodeList = transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList()
                    .stream().map(TransferForecastOrderCreateDetail::getGoodsCode).collect(Collectors.toList());
            Map<String, ScItemResponse> scItemInDOfoMap = getScItemInfoList(scItemCodeList);
            if(scItemInDOfoMap == null){
                return Result.fail("10001","货品不存在");
            }
            if(Nullable.stream(scItemCodeList).distinct().count() > scItemInDOfoMap.values().size()){
                return Result.fail("10001","货品不存在");
            }
            String checkScItemTypeAndStatus = CheckUtil.getCheckScItemTypeAndStatus(scItemInDOfoMap);
            if(checkScItemTypeAndStatus !=null){
                return Result.fail("10001",checkScItemTypeAndStatus);
            }
            //货品单位校验
            String checkScItemMessage = CheckUtil.checkTransferForecastOrderScItem(transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList(), scItemInDOfoMap);
            if(checkScItemMessage != null){
                return Result.fail("10006",checkScItemMessage);
            }
            // 仓库校验
            WarehouseQueryResponse receiveLogicWarehouse = getWarehouseInfo(transferForecastOrderCreateRequest.getReceiveLogicWarehouseCode());
            WarehouseQueryResponse shipLogicWarehouseId = getWarehouseInfo(transferForecastOrderCreateRequest.getDeliveryLogicWarehouseCode());
            String wareHouseMessage = CheckUtil.checkWareHouse(Integer.parseInt(transferForecastOrderCreateRequest.getTransferForecastOrderType()), receiveLogicWarehouse, shipLogicWarehouseId);
            if(wareHouseMessage != null){
                return Result.fail("10006",wareHouseMessage);
            }
            AllocateApplyOrderCreateDTO allocateApplyOrderCreateDTO = convertAllocateApplyOrderCreateDTO(transferForecastOrderCreateRequest,receiveLogicWarehouse,shipLogicWarehouseId);
            // 设置features，业务单元，销售组织编码
            allocateApplyOrderCreateDTO.setFeatures(getFeatures(receiveLogicWarehouse, shipLogicWarehouseId));
            log.info("createTransferForecastOrder_createAllocateApplyOrder,request:{}",JSON.toJSON(allocateApplyOrderCreateDTO));
            Result<AllocateApplyOrderDetailDTO> allocateApplyOrder = allocateApplyOrderWriteService.createAllocateApplyOrder(allocateApplyOrderCreateDTO);

            if(!allocateApplyOrder.isSuccess()){
                return Result.fail( allocateApplyOrder.getErrorCode(), allocateApplyOrder.getMessage());
            }
            AllocateApplyOrderDetailDTO result = allocateApplyOrder.getResult();


            Long allocateApplyOrderId = result.getId();

            //创建明细
            createAllocateApplyOrderDetailSDO(transferForecastOrderCreateRequest, scItemInDOfoMap,allocateApplyOrderId);
            // 是否需要提交：false-不提交 t，rue-已提交  默认 false

            if(Boolean.parseBoolean(transferForecastOrderCreateRequest.getSubmitFlag())){
                //提交：调用调拨预报单提交接口
                AllocateApplyOrderBatchSubmitRequest allocateApplyOrderBatchSubmitRequest = new AllocateApplyOrderBatchSubmitRequest();
                allocateApplyOrderBatchSubmitRequest.setIdList(Collections.singletonList(String.valueOf(result.getId())));
                allocateApplyOrderBatchSubmitRequest.setFromThirdParty(FROM_THIRD_PARTY);
                allocateApplyOrderBatchSubmitRequest.setModifierName(transferForecastOrderCreateRequest.getCreator());
                log.info("createTransferForecastOrder_batchSubmit,request:{}",JSON.toJSON(allocateApplyOrderBatchSubmitRequest));
                allocateApplyOrderWriteService.batchSubmit(allocateApplyOrderBatchSubmitRequest);
            }

            // 返回数据
            TransferForecastOrderCreateResponse transferForecastOrderCreateResponse = new TransferForecastOrderCreateResponse();
            transferForecastOrderCreateResponse.setTransferForecastOrderCode(result.getCode());

            // 查询调拨预报单
            QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
            queryAllocateApplyOrderRequest.setCode(result.getCode());
            Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTOResult = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
            AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = allocateApplyOrderDetailDTOResult.getResult();
            List<AllocateApplyOrderGoodsDetailDTO> allocateApplyOrderGoodsDetailDTOList = allocateApplyOrderDetailDTO.getList();
            if(CollectionUtil.isNotEmpty(allocateApplyOrderGoodsDetailDTOList)){
                List<TransferForecastOrderCreateDetailResponseList> collect = allocateApplyOrderGoodsDetailDTOList.stream().map(x -> {
                    TransferForecastOrderCreateDetailResponseList detail = new TransferForecastOrderCreateDetailResponseList();
                    detail.setOutDetailLineNo(x.getOutLineNo());
                    detail.setDetailLineNo(x.getLineNo());
                    return detail;
                }).collect(Collectors.toList());
                transferForecastOrderCreateResponse.setTransferForecastOrderCreateDetailResponseList(collect);
            }

            return Result.success(transferForecastOrderCreateResponse);

        }catch (Throwable e) {
            log.error("TransferForecastOrderWriteService_createTransferForecastOrder_error req:{} ", JSON.toJSON(transferForecastOrderCreateRequest));
            log.error("create transferForecastOrder error", e);
        }

        return Result.fail("10007","创建预报单失败");
    }

    /**
     * 从仓库(features)中获取销售组织编码（sapOrgCode），业务单元（sapCompanyCode）
     * @param receiveLogicWare 收货仓
     * @param deliveryLogicWare 发货仓
     * @return features (receiveCompanyCode:收货仓业务单元;receiveSapOrgCode:收货仓销售组织;shipCompanyCode:发货仓业务单元;shipSapOrgCode:发货仓销售组织)
     */
    private String getFeatures(WarehouseQueryResponse receiveLogicWare,WarehouseQueryResponse deliveryLogicWare){
        Map<String, String> receiveLogicWareMap = receiveLogicWare.getFeatures();
        Map<String, String> deliveryLogicWareMap = deliveryLogicWare.getFeatures();
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(";");
        if(receiveLogicWareMap.get("sapCompanyCode") != null){
            stringBuffer.append("receiveCompanyCode:").append(receiveLogicWareMap.get("sapCompanyCode")).append(";");
        }
        if(receiveLogicWareMap.get("sapOrgCode") != null){
            stringBuffer.append("receiveSapOrgCode:").append(receiveLogicWareMap.get("sapOrgCode")).append(";");
        }
        if(deliveryLogicWareMap.get("sapCompanyCode") != null){
            stringBuffer.append("shipCompanyCode:").append(deliveryLogicWareMap.get("sapCompanyCode")).append(";");
        }
        if(deliveryLogicWareMap.get("sapOrgCode") != null){
            stringBuffer.append("shipSapOrgCode:").append(deliveryLogicWareMap.get("sapOrgCode")).append(";");
        }
        return stringBuffer.toString();
    }

    private String getFeatures4App(WarehouseQueryResponse receiveLogicWare,WarehouseQueryResponse deliveryLogicWare, TransferForecastOrderCreateRequest request){
        Map<String, String> receiveLogicWareMap = receiveLogicWare.getFeatures();
        Map<String, String> deliveryLogicWareMap = deliveryLogicWare.getFeatures();
        Features features = Features.newFeatures();
        if(receiveLogicWareMap.get("sapCompanyCode") != null) {
            features.addFeature("receiveCompanyCode",receiveLogicWareMap.get("sapCompanyCode"));
        }
        if(receiveLogicWareMap.get("sapOrgCode") != null) {
            features.addFeature("receiveSapOrgCode",receiveLogicWareMap.get("sapOrgCode"));
        }
        if(deliveryLogicWareMap.get("sapCompanyCode") != null) {
            features.addFeature("shipCompanyCode",deliveryLogicWareMap.get("sapCompanyCode"));
        }
        if(deliveryLogicWareMap.get("sapOrgCode") != null) {
            features.addFeature("shipSapOrgCode",deliveryLogicWareMap.get("sapOrgCode"));
        }
        if (StringUtils.isNotBlank(request.getOrderTag())) {
            features.addFeature("order_tag",request.getOrderTag());
        }
        if (StringUtils.isNotBlank(request.getBizUnit())) {
            features.addFeature("biz_unit", request.getBizUnit());
        }
        return features.toString();
    }

    private AllocateApplyOrderCreateDTO convertAllocateApplyOrderCreateDTO(TransferForecastOrderCreateRequest transferForecastOrderCreateRequest,
                                                                           WarehouseQueryResponse receiveLogicWarehouse,WarehouseQueryResponse shipLogicWarehouseId) {
        AllocateApplyOrderCreateDTO allocateApplyOrderCreateDTO = new AllocateApplyOrderCreateDTO();
        allocateApplyOrderCreateDTO.setFromSys(transferForecastOrderCreateRequest.getFromSys());
        allocateApplyOrderCreateDTO.setBusinessType(transferForecastOrderCreateRequest.getBusinessType());
        allocateApplyOrderCreateDTO.setType(Integer.parseInt(transferForecastOrderCreateRequest.getTransferForecastOrderType()));
        allocateApplyOrderCreateDTO.setApplyOrgId(StringUtils.isNotBlank(transferForecastOrderCreateRequest.getApplyOrg()) ? Long.valueOf(transferForecastOrderCreateRequest.getApplyOrg()) : null);
        allocateApplyOrderCreateDTO.setReceiveWarehouseId(Integer.parseInt(receiveLogicWarehouse.getId()));


        allocateApplyOrderCreateDTO.setShipWarehouseId(shipLogicWarehouseId.getId());
        allocateApplyOrderCreateDTO.setOrderTime(strToDate(transferForecastOrderCreateRequest.getOrderDate()));
        allocateApplyOrderCreateDTO.setTakeEffectTime(strToDate(transferForecastOrderCreateRequest.getEffectiveDate()));
        allocateApplyOrderCreateDTO.setInvalidDate(strToDate(transferForecastOrderCreateRequest.getInvalidDate()));
        allocateApplyOrderCreateDTO.setHopeDeliveryTime(strToDate(transferForecastOrderCreateRequest.getExpectedDeliveryDate()));
        allocateApplyOrderCreateDTO.setShipMethod(transferForecastOrderCreateRequest.getShipMethodCode());
        allocateApplyOrderCreateDTO.setHeadquartersOrganizationCode(transferForecastOrderCreateRequest.getHeadquartersOrganizationCode());
        allocateApplyOrderCreateDTO.setHeadquartersChannelCode(transferForecastOrderCreateRequest.getHeadquartersChannelCode());
        allocateApplyOrderCreateDTO.setRemark(transferForecastOrderCreateRequest.getRemark());
        allocateApplyOrderCreateDTO.setFromThirdParty(FROM_THIRD_PARTY);
        allocateApplyOrderCreateDTO.setIsDTC(false);
        allocateApplyOrderCreateDTO.setGoodsGroup(Integer.parseInt(transferForecastOrderCreateRequest.getBusinessType()));
        allocateApplyOrderCreateDTO.setRequestId(transferForecastOrderCreateRequest.getRequestId());
        allocateApplyOrderCreateDTO.setThirdAllocateApplyOrderId(transferForecastOrderCreateRequest.getThirdAllocateApplyOrderId());

//        allocateApplyOrderCreateDTO.setOperator(transferForecastOrderCreateRequest.getCreator());
        allocateApplyOrderCreateDTO.setCreatorName(transferForecastOrderCreateRequest.getCreator());
        allocateApplyOrderCreateDTO.setIsAppCreate(transferForecastOrderCreateRequest.getIsAppCreate() != null && transferForecastOrderCreateRequest.getIsAppCreate());
        return allocateApplyOrderCreateDTO;
    }

    private void createAllocateApplyOrderDetailSDO(TransferForecastOrderCreateRequest transferForecastOrderCreateRequest,
                                                   Map<String, ScItemResponse> scItemInDOfoMap,Long allocateApplyOrderId ){
        // 调用创建调拨预报单详情接口
        int line = 0;
        List<AllocateApplyOrderDetailSDO> collect2= new ArrayList<>();
        for(TransferForecastOrderCreateDetail x:transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList()){
            ScItemResponse scItemRes = scItemInDOfoMap.get(x.getGoodsCode());
            AllocateApplyOrderDetailSDO allocateApplyOrderDetailSDO = new AllocateApplyOrderDetailSDO();
            allocateApplyOrderDetailSDO.setAllocateApplyOrderId(Math.toIntExact(allocateApplyOrderId));
            allocateApplyOrderDetailSDO.setGoodsId(scItemRes.getScItemId());
            allocateApplyOrderDetailSDO.setScItemId(x.getGoodsCode());
            allocateApplyOrderDetailSDO.setTitle(scItemRes.getTitle());
            allocateApplyOrderDetailSDO.setApplyQuantity(Integer.valueOf(x.getQuantity()));
            allocateApplyOrderDetailSDO.setUom(x.getUnit());
            allocateApplyOrderDetailSDO.setStatus(AllocateApplyOrderStatusEnum.DRAFT.getCode());
            allocateApplyOrderDetailSDO.setRemark(x.getRemark());
            allocateApplyOrderDetailSDO.setThirdLineNo(x.getOutDetailLineNo());
            if (StringUtils.isNotBlank(x.getUnitPrice())) {
                allocateApplyOrderDetailSDO.setUnitPrice(new BigDecimal(x.getUnitPrice()));
            }
            allocateApplyOrderDetailSDO.setLineNo(++line);//行号自增

            Features features = Features.newFeatures();
            if (StringUtils.isNotBlank(x.getApplyDeviationReason())) {
                features.addFeature("applyDeviationReason",x.getApplyDeviationReason());
            }
            if (StringUtils.isNotBlank(x.getPlanSuggestQuantity())) {
                features.addFeature("planSuggestQuantity",x.getPlanSuggestQuantity());
            }
            if (StringUtils.isNotBlank(x.getAlgorithmSuggestQuantity())) {
                features.addFeature("algorithmSuggestQuantity",x.getAlgorithmSuggestQuantity());
            }
            if (StringUtils.isNotBlank(x.getAdvanceApplyQuantity())) {
                features.addFeature("advanceApplyQuantity",x.getAdvanceApplyQuantity());
            }
            if (StringUtils.isNotBlank(x.getDistributeRatio())) {
                features.addFeature("biz_unit_ratio",x.getDistributeRatio());
            }
            allocateApplyOrderDetailSDO.setFeatures(features.toString());
            allocateApplyOrderDetailSDO.setBizFeatures(features.toString());
            allocateApplyOrderDetailSDO.setCreatorName(transferForecastOrderCreateRequest.getCreator());
            allocateApplyOrderDetailSDO.setModifierName(transferForecastOrderCreateRequest.getCreator());
            collect2.add(allocateApplyOrderDetailSDO);
        }
        log.info("createTransferForecastOrder_batchCreateAllocateApplyOrderDetail,request:{}",JSON.toJSON(collect2));
        allocateApplyOrderDetailWriteRepository.batchCreateAllocateApplyOrderDetail(collect2);
    }

    /**
     * 通过货品外部编码（goodsCode）查询货品详情goodsInfo(scItem)  getScItemInfoList
     */
    public Map<String, ScItemResponse>  getScItemInfoList(List<String> outerIdList){
        if(CollectionUtils.isEmpty(outerIdList)){
            return null;
        }
        ScItemSearchReqAbilityDTO scItemSearchReqAbilityDTO1 = new ScItemSearchReqAbilityDTO();
        scItemSearchReqAbilityDTO1.setOuterIdList(outerIdList);
        log.info("getScItemInfoList,request:{}",JSON.toJSON(scItemSearchReqAbilityDTO1));
        Result<List<ScItemResponse>> listResult = mnInventoryCenterService.searchScItemFromDbList(scItemSearchReqAbilityDTO1);
        log.info("getScItemInfoList,listResult:{}",JSON.toJSON(listResult));

        List<ScItemResponse> result1 = listResult.getResult();
        if(CollectionUtil.isEmpty(result1)){
            return null;
        }
        return result1.stream().collect(Collectors.toMap(ScItemResponse::getOuterId, Function.identity()));
    }

    /**
     * 根据 仓库编码code查询仓库信息，仓库状态为1（启用）
     * @param warehouseCode code
     * @return WarehouseQueryResponse
     */
    private WarehouseQueryResponse getWarehouseInfo(String warehouseCode){
        WarehouseQueryRequest warehouseQueryRequest = new WarehouseQueryRequest();
        warehouseQueryRequest.setMerchantCode("mengniu");
        warehouseQueryRequest.setCode(warehouseCode);
        log.info("getWarehouseInfo,request:{}",JSON.toJSON(warehouseQueryRequest));
        Result<WarehouseQueryResponse> warehouseResult = mnInventoryCenterService.queryWarehoseByCodeApi(warehouseQueryRequest);
        log.info("getWarehouseInfo,warehouseResult:{}",JSON.toJSON(warehouseResult));
        return warehouseResult.getResult();
    }

    /**
     * 根据仓库id查询仓库ID
     * @param warehouseId id
     * @return WarehouseQueryResponse
     */
    private WarehouseQueryResponse getWarehouseInfoById(String warehouseId){
        if(StringUtils.isBlank(warehouseId)){
            return null;
        }
        QueryWarehouseByIdApiRequest queryWarehouseByIdApiRequest = new QueryWarehouseByIdApiRequest();
        queryWarehouseByIdApiRequest.setWarehouseIds(Collections.singletonList(warehouseId));
        Result<List<WarehouseQueryResponse>> listResult = mnInventoryCenterService.queryWarehouseByIdApi(queryWarehouseByIdApiRequest);
        List<WarehouseQueryResponse> result = listResult.getResult();
        if(CollectionUtils.isEmpty(result)){
            return result.get(0);
        }
        return null;
    }

    private String checkCreateTransferForecastOrder(TransferForecastOrderCreateRequest transferForecastOrderCreateRequest) {
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getFromSys())){
            return "系统来源不能为空";
        }
        if(transferForecastOrderCreateRequest.getFromSys().length() >32){
            return "系统来源字段长度大于32";
        }

        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getBusinessType())){
            return "业态不能为空";
        }
        if(transferForecastOrderCreateRequest.getBusinessType().length() >32){
            return "业态字段长度大于32";
        }
        if(Objects.isNull(transferForecastOrderCreateRequest.getTransferForecastOrderType())){
            return "调拨预报订单订单类型不能为空";
        }
        if(transferForecastOrderCreateRequest.getTransferForecastOrderType().length() >5){
            return "调拨预报单类型长度大于5";
        }
        if(!StringUtils.isNumeric(transferForecastOrderCreateRequest.getTransferForecastOrderType())){
            return "调拨预报单类型非法";
        }
        AllocateOrderTypeEnum allocateOrderTypeEnumType = CheckUtil.getAllocateOrderTypeEnumType(Integer.parseInt(transferForecastOrderCreateRequest.getTransferForecastOrderType()));
        if(allocateOrderTypeEnumType == null){
            return "调拨预报单类型不存在";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getReceiveLogicWarehouseCode())){
            return "收货逻辑仓库id不能为空";
        }
        if(transferForecastOrderCreateRequest.getReceiveLogicWarehouseCode().length() > 32 ){
            return "收货逻辑仓库id字段长度大于32";
        }
        if( StringUtils.isBlank(transferForecastOrderCreateRequest.getDeliveryLogicWarehouseCode())){
            return "发货逻辑仓库id不能为空";
        }
        if(transferForecastOrderCreateRequest.getDeliveryLogicWarehouseCode().length() > 32){
            return "发货逻辑仓库id字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getOrderDate())){
            return "单据日期不能为空";
        }
        if(transferForecastOrderCreateRequest.getOrderDate().length() != 19
                || !CheckUtil.isLegalDate(transferForecastOrderCreateRequest.getOrderDate()) ){
            return "单据日期格式并不正确";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getEffectiveDate())){
            return "生效日期不能为空";
        }
        if(transferForecastOrderCreateRequest.getEffectiveDate().length() != 19
                || !CheckUtil.isLegalDate(transferForecastOrderCreateRequest.getEffectiveDate())){
            return "生效日期格式并不正确";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getInvalidDate())){
            return "失效日期不能为空";
        }
        if(transferForecastOrderCreateRequest.getInvalidDate().length() != 19
                || !CheckUtil.isLegalDate(transferForecastOrderCreateRequest.getInvalidDate())){
            return "失效日期格式并不正确";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getExpectedDeliveryDate())){
            return "期望交货日期不能为空";
        }
        if(transferForecastOrderCreateRequest.getExpectedDeliveryDate().length() != 19
                || !CheckUtil.isLegalDate(transferForecastOrderCreateRequest.getExpectedDeliveryDate())){
            return "期望交货日期格式并不正确";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getShipMethodCode())){
            return "运输方式编码不能为空";
        }
        if(transferForecastOrderCreateRequest.getShipMethodCode().length() >32){
            return "运输方式编码字段长度大于32";
        }
        if (Objects.isNull(TransportModeEnum.of(transferForecastOrderCreateRequest.getShipMethodCode()))){
            return "运输方式编码不存在";
        }

        if( StringUtils.isBlank(transferForecastOrderCreateRequest.getHeadquartersOrganizationCode())){
            return "总部组织编码不能为空";
        }
        if(transferForecastOrderCreateRequest.getHeadquartersOrganizationCode().length() >32){
            return "总部组织编码字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getHeadquartersChannelCode())){
            return "总部渠道编码不能为空";
        }
        if(transferForecastOrderCreateRequest.getHeadquartersChannelCode().length() >32){
            return "总部渠道编码字段长度大于32";
        }
        if (StrUtil.isBlank(transferForecastOrderCreateRequest.getSubmitFlag())){
            return "是否提交不能为空";
        }
        if (transferForecastOrderCreateRequest.getSubmitFlag().length()>5){
            return "是否提交长度大于5";
        }
        if (!transferForecastOrderCreateRequest.getSubmitFlag().matches("^true|false$")){
            return "是否提交错误";
        }
        if(CollectionUtil.isEmpty(transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList())){
            return "调拨预报单详情不能为空";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getRequestId())){
            return "请求id不能为空";
        }
        if(transferForecastOrderCreateRequest.getRequestId().length() >32){
            return "请求id字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getThirdAllocateApplyOrderId())){
            return "三方系统调拨预报单编码不能为空";
        }
        if(transferForecastOrderCreateRequest.getThirdAllocateApplyOrderId().length() >32){
            return "三方系统调拨预报单编码字段长度大于32";
        }
        if(StringUtils.isNotEmpty(transferForecastOrderCreateRequest.getRemark())){
            if(transferForecastOrderCreateRequest.getRemark().length() >200){
                return "remark字段长度大于200";
            }
        }
        if (StringUtils.isNotBlank(transferForecastOrderCreateRequest.getCreator())){
            if (transferForecastOrderCreateRequest.getCreator().length() > 32){
                return "creator字段长度大于32";
            }
        }

        if(CollectionUtils.isEmpty(transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList())){
            return "货品详情不能为空";
        }
        // 外部行号是否重复
        List<String> collect = transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList()
                .stream().map(TransferForecastOrderCreateDetail::getOutDetailLineNo).distinct().collect(Collectors.toList());
        if(transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList().size() >collect.size()){
            return "外部行号不能重复";
        }
        for(TransferForecastOrderCreateDetail x:transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList()){
            if(StringUtils.isBlank(x.getGoodsCode())){
                return "货品编码不能为空";
            }
            if(x.getGoodsCode().length() >32){
                return "货品编码字段长度大于32";
            }
            if(StringUtils.isBlank(x.getUnit())){
                return "单位不能为空";
            }
            if(x.getUnit().length() >32){
                return "单位字段长度大于32";
            }
            if(StringUtils.isBlank(x.getOutDetailLineNo())){
                return "外部行号不能为空";
            }
            if(x.getOutDetailLineNo().length() >32){
                return "外部行号字段长度大于32";
            }
            if(StringUtils.isNotBlank(x.getRemark())){
                if(x.getRemark().length() >200){
                    return "行备注字段长度大于200";
                }
            }
            if(StringUtils.isBlank(x.getQuantity())){
                return "数量不能为空";
            }
            if(x.getQuantity().length() > 10){
                return "数量长度不能大于10";
            }
            if(!StringUtils.isNumeric(x.getQuantity())){
                return "数量输入非法";
            }
        }
        if (!checkDictionary(FROM_SYS_GROUP,transferForecastOrderCreateRequest.getFromSys())){
            return "系统来源错误";
        }
        if (!checkDictionary(BUSINESS_TYPE_GROUP,transferForecastOrderCreateRequest.getBusinessType())){
            return "业态错误";
        }
        return null;
    }

    private String checkCreateTransferForecastOrderV2(TransferForecastOrderCreateRequest transferForecastOrderCreateRequest) {
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getFromSys())){
            return "系统来源不能为空";
        }
        if(transferForecastOrderCreateRequest.getFromSys().length() >32){
            return "系统来源字段长度大于32";
        }

        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getBusinessType())){
            return "业态不能为空";
        }
        if(transferForecastOrderCreateRequest.getBusinessType().length() >32){
            return "业态字段长度大于32";
        }
        if(Objects.isNull(transferForecastOrderCreateRequest.getTransferForecastOrderType())){
            return "调拨预报订单订单类型不能为空";
        }
        if(transferForecastOrderCreateRequest.getTransferForecastOrderType().length() >5){
            return "调拨预报单类型长度大于5";
        }
        if(!StringUtils.isNumeric(transferForecastOrderCreateRequest.getTransferForecastOrderType())){
            return "调拨预报单类型非法";
        }
        AllocateOrderTypeEnum allocateOrderTypeEnumType = CheckUtil.getAllocateOrderTypeEnumType(Integer.parseInt(transferForecastOrderCreateRequest.getTransferForecastOrderType()));
        if(allocateOrderTypeEnumType == null){
            return "调拨预报单类型不存在";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getReceiveLogicWarehouseCode())){
            return "收货逻辑仓库id不能为空";
        }
        if(transferForecastOrderCreateRequest.getReceiveLogicWarehouseCode().length() > 32 ){
            return "收货逻辑仓库id字段长度大于32";
        }
        if( StringUtils.isBlank(transferForecastOrderCreateRequest.getDeliveryLogicWarehouseCode())){
            return "发货逻辑仓库id不能为空";
        }
        if(transferForecastOrderCreateRequest.getDeliveryLogicWarehouseCode().length() > 32){
            return "发货逻辑仓库id字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getOrderDate())){
            return "单据日期不能为空";
        }
        if(transferForecastOrderCreateRequest.getOrderDate().length() != 19
                || !CheckUtil.isLegalDate(transferForecastOrderCreateRequest.getOrderDate()) ){
            return "单据日期格式并不正确";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getEffectiveDate())){
            return "生效日期不能为空";
        }
        if(transferForecastOrderCreateRequest.getEffectiveDate().length() != 19
                || !CheckUtil.isLegalDate(transferForecastOrderCreateRequest.getEffectiveDate())){
            return "生效日期格式并不正确";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getInvalidDate())){
            return "失效日期不能为空";
        }
        if(transferForecastOrderCreateRequest.getInvalidDate().length() != 19
                || !CheckUtil.isLegalDate(transferForecastOrderCreateRequest.getInvalidDate())){
            return "失效日期格式并不正确";
        }

        // 失效日期必须在生效日期之后
        String invalidDate = transferForecastOrderCreateRequest.getInvalidDate();
        String effectiveDate = transferForecastOrderCreateRequest.getEffectiveDate();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date invalid = simpleDateFormat.parse(invalidDate);
            Date effective = simpleDateFormat.parse(effectiveDate);
            if (invalid.before(effective)) {
                return "生效至日期必须在生效日期之后";
            }
        } catch (ParseException e) {
            // ignore
        }


        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getExpectedDeliveryDate())){
            return "期望交货日期不能为空";
        }
        if(transferForecastOrderCreateRequest.getExpectedDeliveryDate().length() != 19
                || !CheckUtil.isLegalDate(transferForecastOrderCreateRequest.getExpectedDeliveryDate())){
            return "期望交货日期格式并不正确";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getShipMethodCode())){
            return "运输方式编码不能为空";
        }
        if(transferForecastOrderCreateRequest.getShipMethodCode().length() >32){
            return "运输方式编码字段长度大于32";
        }
        if (Objects.isNull(TransportModeEnum.of(transferForecastOrderCreateRequest.getShipMethodCode()))){
            return "运输方式编码不存在";
        }

        if( StringUtils.isBlank(transferForecastOrderCreateRequest.getHeadquartersOrganizationCode())){
            return "总部组织编码不能为空";
        }
        if(transferForecastOrderCreateRequest.getHeadquartersOrganizationCode().length() >32){
            return "总部组织编码字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getHeadquartersChannelCode())){
            return "总部渠道编码不能为空";
        }
        if(transferForecastOrderCreateRequest.getHeadquartersChannelCode().length() >32){
            return "总部渠道编码字段长度大于32";
        }
        if (StrUtil.isBlank(transferForecastOrderCreateRequest.getSubmitFlag())){
            return "是否提交不能为空";
        }
        if (transferForecastOrderCreateRequest.getSubmitFlag().length()>5){
            return "是否提交长度大于5";
        }
        if (!transferForecastOrderCreateRequest.getSubmitFlag().matches("^true|false$")){
            return "是否提交错误";
        }
        if(CollectionUtil.isEmpty(transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList())){
            return "调拨预报单详情不能为空";
        }
        if(StringUtils.isBlank(transferForecastOrderCreateRequest.getRequestId())){
            return "请求id不能为空";
        }
        if(transferForecastOrderCreateRequest.getRequestId().length() >32){
            return "请求id字段长度大于32";
        }
        if(StringUtils.isNotBlank(transferForecastOrderCreateRequest.getThirdAllocateApplyOrderId()) && transferForecastOrderCreateRequest.getThirdAllocateApplyOrderId().length() >32){
            return "三方系统调拨预报单编码字段长度大于32";
        }
        if(StringUtils.isNotEmpty(transferForecastOrderCreateRequest.getRemark())){
            if(transferForecastOrderCreateRequest.getRemark().length() >200){
                return "remark字段长度大于200";
            }
        }

        if(CollectionUtils.isEmpty(transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList())){
            return "货品详情不能为空";
        }

        for(TransferForecastOrderCreateDetail x:transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList()){
            if(StringUtils.isBlank(x.getGoodsCode())){
                return "货品编码不能为空";
            }
            if(x.getGoodsCode().length() >32){
                return "货品编码字段长度大于32";
            }
            if(StringUtils.isBlank(x.getUnit())){
                return "单位不能为空";
            }
            if(x.getUnit().length() >32){
                return "单位字段长度大于32";
            }

            if(StringUtils.isNotBlank(x.getOutDetailLineNo()) && x.getOutDetailLineNo().length() >32){
                return "外部行号字段长度大于32";
            }
            if(StringUtils.isNotBlank(x.getRemark())){
                if(x.getRemark().length() >200){
                    return "行备注字段长度大于200";
                }
            }
            if(StringUtils.isBlank(x.getQuantity())){
                return "数量不能为空";
            }
            if(x.getQuantity().length() > 10){
                return "数量长度不能大于10";
            }
            if(!StringUtils.isNumeric(x.getQuantity())){
                return "数量输入非法";
            }
        }
        if (!checkDictionary(FROM_SYS_GROUP,transferForecastOrderCreateRequest.getFromSys())){
            return "系统来源错误";
        }
        if (!checkDictionary(BUSINESS_TYPE_GROUP,transferForecastOrderCreateRequest.getBusinessType())){
            return "业态错误";
        }
        return null;
    }

    @Override
    @FacadeInvoker(value = "修改调拨预报单")
    public Result<Boolean> updateTransferForecastOrder(TransferForecastOrderUpdateRequest transferForecastOrderUpdateRequest) {
        String message = checkUpdateTransferForecastOrder(transferForecastOrderUpdateRequest);
        if (message !=null) {
            return Result.fail("10000",message);
        }
        /*String dateMessage = checkUpdateTransferForecastOrderDate(transferForecastOrderUpdateRequest);
        if (dateMessage != null){
            return Result.fail("10003",dateMessage);
        }*/
        QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
        queryAllocateApplyOrderRequest.setCode(transferForecastOrderUpdateRequest.getTransferForecastOrderCode());
        queryAllocateApplyOrderRequest.setBusinessType(transferForecastOrderUpdateRequest.getBusinessType());
        queryAllocateApplyOrderRequest.setFromSys(transferForecastOrderUpdateRequest.getFromSys());
        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTOResult = allocateApplyOrderReadService.queryAllocateApplyOrder(queryAllocateApplyOrderRequest);
        if(allocateApplyOrderDetailDTOResult.getResult() == null){
            return Result.fail("10001","调拨单不存在");
        }
        AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = allocateApplyOrderDetailDTOResult.getResult();
        if(allocateApplyOrderDetailDTO.getId() == null){
            return Result.fail("10001","调拨单不存在");
        }

        AllocateApplyOrderUpdateDTO allocateApplyOrderUpdateDTO = new AllocateApplyOrderUpdateDTO();
        allocateApplyOrderUpdateDTO.setFromSys(transferForecastOrderUpdateRequest.getFromSys());
        allocateApplyOrderUpdateDTO.setBusinessType(transferForecastOrderUpdateRequest.getBusinessType());

        allocateApplyOrderUpdateDTO.setCode(transferForecastOrderUpdateRequest.getTransferForecastOrderCode());
        WarehouseQueryResponse receiveLogicWarehouse= getWarehouseInfo(transferForecastOrderUpdateRequest.getReceiveLogicWarehouseCode());
        String receiveLogicMessage = CheckUtil.checkWareHouseInfo(receiveLogicWarehouse);
        if( receiveLogicMessage != null){
            return Result.fail("10001",receiveLogicMessage);
        }
        if(receiveLogicWarehouse.getId() != null){
            allocateApplyOrderUpdateDTO.setReceiveWarehouseId(Integer.valueOf(receiveLogicWarehouse.getId()));
        }
        WarehouseQueryResponse deliveryLogicWarehouseCode = getWarehouseInfo(transferForecastOrderUpdateRequest.getDeliveryLogicWarehouseCode());

        String deliveryLogicMessage = CheckUtil.checkWareHouseInfo(receiveLogicWarehouse);
        if( deliveryLogicMessage != null){
            return Result.fail("10001",deliveryLogicMessage);
        }
        if(deliveryLogicWarehouseCode.getId() != null){
            allocateApplyOrderUpdateDTO.setShipWarehouseId(deliveryLogicWarehouseCode.getId());
        }
        // 仓库校验
        String wareHouseMessage = CheckUtil.checkWareHouse(Integer.parseInt(allocateApplyOrderDetailDTO.getType()), receiveLogicWarehouse, deliveryLogicWarehouseCode);
        if(wareHouseMessage != null){
            return Result.fail("10006",wareHouseMessage);
        }
        allocateApplyOrderUpdateDTO.setOrderTime(strToDate(transferForecastOrderUpdateRequest.getOrderDate()));
        allocateApplyOrderUpdateDTO.setTakeEffectTime(strToDate(transferForecastOrderUpdateRequest.getEffectiveDate()));
        allocateApplyOrderUpdateDTO.setInvalidDate(strToDate(transferForecastOrderUpdateRequest.getExpireDate()));
        allocateApplyOrderUpdateDTO.setHopeDeliveryTime(strToDate(transferForecastOrderUpdateRequest.getExpectedDeliveryDate()));
        allocateApplyOrderUpdateDTO.setShipMethod(transferForecastOrderUpdateRequest.getShipMethodCode());
        allocateApplyOrderUpdateDTO.setHeadquartersOrganizationCode(transferForecastOrderUpdateRequest.getHeadquartersOrganizationCode());
        allocateApplyOrderUpdateDTO.setRemark(transferForecastOrderUpdateRequest.getRemark());

//        allocateApplyOrderUpdateDTO.setUpdater(transferForecastOrderUpdateRequest.getModifier());
        List<TransferForecastOrderUpdateDetail> transferForecastOrderUpdateDetailList = transferForecastOrderUpdateRequest.getTransferForecastOrderUpdateDetailList();
        if(CollectionUtil.isNotEmpty(transferForecastOrderUpdateDetailList)){
            List<String> goodsCodeList = transferForecastOrderUpdateDetailList.stream().map(TransferForecastOrderUpdateDetail::getGoodsCode).collect(Collectors.toList());

            Map<String, ScItemResponse> scItemInDOfoMap = getScItemInfoList(goodsCodeList);

            if(scItemInDOfoMap == null){
                return Result.fail("10001","货品不存在");
            }
            if(goodsCodeList.size() > scItemInDOfoMap.values().size()){
                return Result.fail("10001","货品不存在");
            }
            //货品单位校验
            String checkScItemMessage = CheckUtil.checkUpdateTransferForecastOrderScItem(transferForecastOrderUpdateDetailList, scItemInDOfoMap);
            if(checkScItemMessage != null){
                return Result.fail("10003",checkScItemMessage);
            }
            List<AllocateApplyOrderDetailCreateDTO> allocateApplyOrderDetailCreateList = getAllocateApplyOrderDetailCreateDTO(transferForecastOrderUpdateDetailList,scItemInDOfoMap);
            allocateApplyOrderUpdateDTO.setList(allocateApplyOrderDetailCreateList);
        }
        // 获取预报单ID
        if(!Objects.isNull(allocateApplyOrderDetailDTOResult.getResult())){
            allocateApplyOrderUpdateDTO.setId(allocateApplyOrderDetailDTOResult.getResult().getId());
        }
        allocateApplyOrderUpdateDTO.setFromThirdParty(FROM_THIRD_PARTY);
        // 设置features，业务单元，销售组织编码
        allocateApplyOrderUpdateDTO.setFeatures(getFeatures(receiveLogicWarehouse, deliveryLogicWarehouseCode));
        Result<Boolean> booleanResult = allocateApplyOrderWriteService.updateAllocateApplyOrder(allocateApplyOrderUpdateDTO);

        //是否提交
        if(Boolean.parseBoolean(transferForecastOrderUpdateRequest.getSubmitFlag())){
            AllocateApplyOrderBatchSubmitRequest allocateApplyOrderBatchSubmitRequest = new AllocateApplyOrderBatchSubmitRequest();
            allocateApplyOrderBatchSubmitRequest.setIdList(Collections.singletonList(String.valueOf(allocateApplyOrderDetailDTO.getId())));
            allocateApplyOrderBatchSubmitRequest.setFromThirdParty(FROM_THIRD_PARTY);
            allocateApplyOrderWriteService.batchSubmit(allocateApplyOrderBatchSubmitRequest);
        }
        return booleanResult;
    }

    @Override
    @FacadeInvoker(value = "修改调拨预报单-一盘货应用")
    public Result<Boolean> updateTransferForecastOrderV2(TransferForecastOrderUpdateRequest transferForecastOrderUpdateRequest) {
        String message = checkUpdateTransferForecastOrderV2(transferForecastOrderUpdateRequest);
        if (message !=null) {
            return Result.fail("10000",message);
        }

        QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
        queryAllocateApplyOrderRequest.setCode(transferForecastOrderUpdateRequest.getTransferForecastOrderCode());
        queryAllocateApplyOrderRequest.setBusinessType(transferForecastOrderUpdateRequest.getBusinessType());
        queryAllocateApplyOrderRequest.setFromSys(transferForecastOrderUpdateRequest.getFromSys());
        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTOResult = allocateApplyOrderReadService.queryAllocateApplyOrder(queryAllocateApplyOrderRequest);
        if(allocateApplyOrderDetailDTOResult.getResult() == null){
            return Result.fail("10001","调拨单不存在");
        }
        AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = allocateApplyOrderDetailDTOResult.getResult();
        if(allocateApplyOrderDetailDTO.getId() == null){
            return Result.fail("10001","调拨单不存在");
        }

        AllocateApplyOrderUpdateDTO allocateApplyOrderUpdateDTO = new AllocateApplyOrderUpdateDTO();
        allocateApplyOrderUpdateDTO.setFromSys(transferForecastOrderUpdateRequest.getFromSys());
        allocateApplyOrderUpdateDTO.setBusinessType(transferForecastOrderUpdateRequest.getBusinessType());
        allocateApplyOrderUpdateDTO.setOperator(transferForecastOrderUpdateRequest.getUpdater());
        allocateApplyOrderUpdateDTO.setCode(transferForecastOrderUpdateRequest.getTransferForecastOrderCode());
        WarehouseQueryResponse receiveLogicWarehouse= getWarehouseInfo(transferForecastOrderUpdateRequest.getReceiveLogicWarehouseCode());
        String receiveLogicMessage = CheckUtil.checkWareHouseInfo(receiveLogicWarehouse);
        if( receiveLogicMessage != null){
            return Result.fail("10001",receiveLogicMessage);
        }
        if(receiveLogicWarehouse.getId() != null){
            allocateApplyOrderUpdateDTO.setReceiveWarehouseId(Integer.valueOf(receiveLogicWarehouse.getId()));
        }
        WarehouseQueryResponse deliveryLogicWarehouseCode = getWarehouseInfo(transferForecastOrderUpdateRequest.getDeliveryLogicWarehouseCode());

        String deliveryLogicMessage = CheckUtil.checkWareHouseInfo(receiveLogicWarehouse);
        if( deliveryLogicMessage != null){
            return Result.fail("10001",deliveryLogicMessage);
        }
        if(deliveryLogicWarehouseCode.getId() != null){
            allocateApplyOrderUpdateDTO.setShipWarehouseId(deliveryLogicWarehouseCode.getId());
        }
        // 仓库校验
        String wareHouseMessage = CheckUtil.checkWareHouse(Integer.parseInt(allocateApplyOrderDetailDTO.getType()), receiveLogicWarehouse, deliveryLogicWarehouseCode);
        if(wareHouseMessage != null){
            return Result.fail("10006",wareHouseMessage);
        }
        allocateApplyOrderUpdateDTO.setOrderTime(strToDate(transferForecastOrderUpdateRequest.getOrderDate()));
        allocateApplyOrderUpdateDTO.setTakeEffectTime(strToDate(transferForecastOrderUpdateRequest.getEffectiveDate()));
        allocateApplyOrderUpdateDTO.setInvalidDate(strToDate(transferForecastOrderUpdateRequest.getExpireDate()));
        allocateApplyOrderUpdateDTO.setHopeDeliveryTime(strToDate(transferForecastOrderUpdateRequest.getExpectedDeliveryDate()));
        allocateApplyOrderUpdateDTO.setShipMethod(transferForecastOrderUpdateRequest.getShipMethodCode());
        allocateApplyOrderUpdateDTO.setHeadquartersOrganizationCode(transferForecastOrderUpdateRequest.getHeadquartersOrganizationCode());
        allocateApplyOrderUpdateDTO.setRemark(transferForecastOrderUpdateRequest.getRemark());

//        allocateApplyOrderUpdateDTO.setUpdater(transferForecastOrderUpdateRequest.getModifier());
        List<TransferForecastOrderUpdateDetail> transferForecastOrderUpdateDetailList = transferForecastOrderUpdateRequest.getTransferForecastOrderUpdateDetailList();
        if(CollectionUtil.isNotEmpty(transferForecastOrderUpdateDetailList)){
            List<String> goodsCodeList = transferForecastOrderUpdateDetailList.stream().map(TransferForecastOrderUpdateDetail::getGoodsCode).collect(Collectors.toList());

            Map<String, ScItemResponse> scItemInDOfoMap = getScItemInfoList(goodsCodeList);

            if(scItemInDOfoMap == null){
                return Result.fail("10001","货品不存在");
            }
            if(goodsCodeList.size() > scItemInDOfoMap.values().size()){
                return Result.fail("10001","货品不存在");
            }
            //货品单位校验
            String checkScItemMessage = CheckUtil.checkUpdateTransferForecastOrderScItem(transferForecastOrderUpdateDetailList, scItemInDOfoMap);
            if(checkScItemMessage != null){
                return Result.fail("10003",checkScItemMessage);
            }
            List<AllocateApplyOrderDetailCreateDTO> allocateApplyOrderDetailCreateList = getAllocateApplyOrderDetailCreateDTO(transferForecastOrderUpdateDetailList,scItemInDOfoMap);
            allocateApplyOrderUpdateDTO.setList(allocateApplyOrderDetailCreateList);
        }
        // 获取预报单ID
        if(!Objects.isNull(allocateApplyOrderDetailDTOResult.getResult())){
            allocateApplyOrderUpdateDTO.setId(allocateApplyOrderDetailDTOResult.getResult().getId());
        }
        allocateApplyOrderUpdateDTO.setFromThirdParty(FROM_THIRD_PARTY);
        Result<Boolean> booleanResult = allocateApplyOrderWriteService.updateAllocateApplyOrder(allocateApplyOrderUpdateDTO);

        //是否提交
        if(Boolean.parseBoolean(transferForecastOrderUpdateRequest.getSubmitFlag())){
            AllocateApplyOrderBatchSubmitRequest allocateApplyOrderBatchSubmitRequest = new AllocateApplyOrderBatchSubmitRequest();
            allocateApplyOrderBatchSubmitRequest.setIdList(Collections.singletonList(String.valueOf(allocateApplyOrderDetailDTO.getId())));
            allocateApplyOrderBatchSubmitRequest.setFromThirdParty(FROM_THIRD_PARTY);
            allocateApplyOrderWriteService.batchSubmit(allocateApplyOrderBatchSubmitRequest);
        }
        return booleanResult;
    }

    private String checkUpdateTransferForecastOrder(TransferForecastOrderUpdateRequest updateRequest) {
        if(StringUtils.isBlank(updateRequest.getFromSys())){
            return "系统来源不能为空";
        }
        if(updateRequest.getFromSys().length() >32){
            return "系统来源字段长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getBusinessType())){
            return "业态不能为空";
        }
        if(updateRequest.getBusinessType().length() >32){
            return "业态字段长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getTransferForecastOrderCode() )){
            return "调拨预报单号不能为空";
        }
        if(updateRequest.getTransferForecastOrderCode().length() >32){
            return "调拨预报单号长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getReceiveLogicWarehouseCode())){
            return "收货逻辑仓库code不能为空";
        }
        if(updateRequest.getReceiveLogicWarehouseCode().length() >32){
            return "收货逻辑仓库code长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getDeliveryLogicWarehouseCode())){
            return "发货逻辑仓库code不能为空";
        }
        if(updateRequest.getDeliveryLogicWarehouseCode().length() >32){
            return "发货逻辑仓库code长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getOrderDate())){
            return "单据日期不能为空";
        }
        if(updateRequest.getOrderDate().length() != 19
                || !CheckUtil.isLegalDate(updateRequest.getOrderDate())){
            return "单据日期格式不正确";
        }
        if(StringUtils.isBlank(updateRequest.getEffectiveDate())){
            return "生效日期不能为空";
        }
        if(updateRequest.getEffectiveDate().length() != 19
                || !CheckUtil.isLegalDate(updateRequest.getEffectiveDate())){
            return "生效日期格式不正确";
        }
        if(StringUtils.isBlank(updateRequest.getExpireDate())){
            return "失效日期不能为空";
        }
        if(updateRequest.getExpireDate().length() != 19
                || !CheckUtil.isLegalDate(updateRequest.getExpireDate())){
            return "失效日期格式不正确";
        }
        if(StringUtils.isBlank(updateRequest.getExpectedDeliveryDate())){
            return "期望交货日期不能为空";
        }
        if(updateRequest.getExpectedDeliveryDate().length() != 19
                || !CheckUtil.isLegalDate(updateRequest.getExpectedDeliveryDate())){
            return "期望日期格式不正确";
        }
        if(StringUtils.isBlank(updateRequest.getShipMethodCode() )){
            return "运输方式编码不能为空";
        }
        if(updateRequest.getShipMethodCode().length() >32){
            return "运输方式编码长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getHeadquartersOrganizationCode())){
            return "总部销售组织编码不能为空";
        }
        if(updateRequest.getHeadquartersOrganizationCode().length() >32){
            return "总部销售组织编码长度大于32";
        }
        if (StrUtil.isBlank(updateRequest.getSubmitFlag())){
            return "是否提交不能为空";
        }
        if (updateRequest.getSubmitFlag().length() >5){
            return "是否提交长度大于5";
        }
        if (!updateRequest.getSubmitFlag().matches("^true|false$")){
            return "是否提交格式不正确";
        }
        if (StringUtils.isNotBlank(updateRequest.getRemark()) && updateRequest.getRemark().length() > 200) {
            return "抬头备注编码长度大于200";
        }
        if(CollectionUtils.isNotEmpty(updateRequest.getTransferForecastOrderUpdateDetailList())){
            // 外部行号是否重复
            List<String> collect = updateRequest.getTransferForecastOrderUpdateDetailList()
                    .stream().map(TransferForecastOrderUpdateDetail::getOutDetailLineNo).distinct().collect(Collectors.toList());
            boolean containsNull = collect.stream().anyMatch(Objects::isNull);
            if(containsNull){
                return "外部行号不可以为空";
            }
            if(updateRequest.getTransferForecastOrderUpdateDetailList().size() >collect.size()){
                return "外部行号不能重复";
            }
            for(TransferForecastOrderUpdateDetail x:updateRequest.getTransferForecastOrderUpdateDetailList()){
                if(StringUtils.isBlank(x.getGoodsCode())){
                    return "货品编码不能为空";
                }
                if(x.getGoodsCode().length() >32){
                    return "货品编码字段长度大于32";
                }
                if(StringUtils.isBlank(x.getUnit())){
                    return "单位不能为空";
                }
                if(x.getUnit().length() >32){
                    return "单位字段长度大于32";
                }
                if(StringUtils.isBlank(x.getOutDetailLineNo())){
                    return "外部单号不能为空";
                }
                if(x.getOutDetailLineNo().length() >32){
                    return "外部单号字段长度大于32";
                }
                if(StringUtils.isBlank(x.getQuantity())){
                    return "数量不能为空";
                }
                if(x.getQuantity().length() > 10){
                    return "数量长度不能大于10位";
                }
                if(!StringUtils.isNumeric(x.getQuantity())){
                    return "数量输入非法";
                }
                if (StringUtils.isNotBlank(x.getRemark()) && x.getRemark().length() > 200) {
                    return "行备注编码长度大于200";
                }
            }
        }


        if (Objects.isNull(TransportModeEnum.of(updateRequest.getShipMethodCode()))){
            return "运输方式编码不存在";
        }
        String s = checkFromSysAndBusinessType(updateRequest.getFromSys(), updateRequest.getBusinessType());
        if(s != null){
            return s;
        }
        return null;
    }

    private String checkUpdateTransferForecastOrderV2(TransferForecastOrderUpdateRequest updateRequest) {
        if(StringUtils.isBlank(updateRequest.getFromSys())){
            return "系统来源不能为空";
        }
        if(updateRequest.getFromSys().length() >32){
            return "系统来源字段长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getBusinessType())){
            return "业态不能为空";
        }
        if(updateRequest.getBusinessType().length() >32){
            return "业态字段长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getTransferForecastOrderCode() )){
            return "调拨预报单号不能为空";
        }
        if(updateRequest.getTransferForecastOrderCode().length() >32){
            return "调拨预报单号长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getReceiveLogicWarehouseCode())){
            return "收货逻辑仓库code不能为空";
        }
        if(updateRequest.getReceiveLogicWarehouseCode().length() >32){
            return "收货逻辑仓库code长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getDeliveryLogicWarehouseCode())){
            return "发货逻辑仓库code不能为空";
        }
        if(updateRequest.getDeliveryLogicWarehouseCode().length() >32){
            return "发货逻辑仓库code长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getOrderDate())){
            return "单据日期不能为空";
        }
        if(updateRequest.getOrderDate().length() != 19
                || !CheckUtil.isLegalDate(updateRequest.getOrderDate())){
            return "单据日期格式不正确";
        }
        if(StringUtils.isBlank(updateRequest.getEffectiveDate())){
            return "生效日期不能为空";
        }
        if(updateRequest.getEffectiveDate().length() != 19
                || !CheckUtil.isLegalDate(updateRequest.getEffectiveDate())){
            return "生效日期格式不正确";
        }
        if(StringUtils.isBlank(updateRequest.getExpireDate())){
            return "失效日期不能为空";
        }
        if(updateRequest.getExpireDate().length() != 19
                || !CheckUtil.isLegalDate(updateRequest.getExpireDate())){
            return "失效日期格式不正确";
        }
        if(StringUtils.isBlank(updateRequest.getExpectedDeliveryDate())){
            return "期望交货日期不能为空";
        }
        if(updateRequest.getExpectedDeliveryDate().length() != 19
                || !CheckUtil.isLegalDate(updateRequest.getExpectedDeliveryDate())){
            return "期望日期格式不正确";
        }
        if(StringUtils.isBlank(updateRequest.getShipMethodCode() )){
            return "运输方式编码不能为空";
        }
        if(updateRequest.getShipMethodCode().length() >32){
            return "运输方式编码长度大于32";
        }
        if(StringUtils.isBlank(updateRequest.getHeadquartersOrganizationCode())){
            return "总部销售组织编码不能为空";
        }
        if(updateRequest.getHeadquartersOrganizationCode().length() >32){
            return "总部销售组织编码长度大于32";
        }
        if (StrUtil.isBlank(updateRequest.getSubmitFlag())){
            return "是否提交不能为空";
        }
        if (updateRequest.getSubmitFlag().length() >5){
            return "是否提交长度大于5";
        }
        if (!updateRequest.getSubmitFlag().matches("^true|false$")){
            return "是否提交格式不正确";
        }
        if (StringUtils.isNotBlank(updateRequest.getRemark()) && updateRequest.getRemark().length() > 200) {
            return "抬头备注编码长度大于200";
        }
        if(CollectionUtils.isNotEmpty(updateRequest.getTransferForecastOrderUpdateDetailList())){
            // 外部行号是否重复
            List<String> collect = updateRequest.getTransferForecastOrderUpdateDetailList()
                    .stream().map(TransferForecastOrderUpdateDetail::getOutDetailLineNo).distinct().collect(Collectors.toList());

            if(updateRequest.getTransferForecastOrderUpdateDetailList().size() >collect.size()){
                return "外部行号不能重复";
            }
            for(TransferForecastOrderUpdateDetail x:updateRequest.getTransferForecastOrderUpdateDetailList()){
                if(StringUtils.isBlank(x.getGoodsCode())){
                    return "货品编码不能为空";
                }
                if(x.getGoodsCode().length() >32){
                    return "货品编码字段长度大于32";
                }
                if(StringUtils.isBlank(x.getUnit())){
                    return "单位不能为空";
                }
                if(x.getUnit().length() >32){
                    return "单位字段长度大于32";
                }

                if(StringUtils.isBlank(x.getQuantity())){
                    return "数量不能为空";
                }
                if(x.getQuantity().length() > 10){
                    return "数量长度不能大于10位";
                }
                if(!StringUtils.isNumeric(x.getQuantity())){
                    return "数量输入非法";
                }
                if (StringUtils.isNotBlank(x.getRemark()) && x.getRemark().length() > 200) {
                    return "行备注编码长度大于200";
                }
            }
        }


        if (Objects.isNull(TransportModeEnum.of(updateRequest.getShipMethodCode()))){
            return "运输方式编码不存在";
        }
        return checkFromSysAndBusinessType(updateRequest.getFromSys(), updateRequest.getBusinessType());
    }

    private List<AllocateApplyOrderDetailCreateDTO> getAllocateApplyOrderDetailCreateDTO(List<TransferForecastOrderUpdateDetail> transferForecastOrderUpdateDetailList,
                                                                                         Map<String, ScItemResponse> scItemInfoList){
        int line = 0;
        List<AllocateApplyOrderDetailCreateDTO> allocateApplyOrderDetailList= new ArrayList<>();
        for(TransferForecastOrderUpdateDetail x:transferForecastOrderUpdateDetailList){
            ScItemResponse scItemResponse = scItemInfoList.get(x.getGoodsCode());
            AllocateApplyOrderDetailCreateDTO allocateApplyOrderDetailCreateDTO = new AllocateApplyOrderDetailCreateDTO();
            allocateApplyOrderDetailCreateDTO.setGoodsId(scItemResponse.getScItemId());
            allocateApplyOrderDetailCreateDTO.setScItemId(x.getGoodsCode());
            allocateApplyOrderDetailCreateDTO.setTitle(scItemResponse.getTitle());
            allocateApplyOrderDetailCreateDTO.setApplyQuantity(Integer.valueOf(x.getQuantity()));
            allocateApplyOrderDetailCreateDTO.setRemark(x.getRemark());
            allocateApplyOrderDetailCreateDTO.setThirdLineNo(x.getOutDetailLineNo());
            allocateApplyOrderDetailCreateDTO.setUom(x.getUnit());
            allocateApplyOrderDetailCreateDTO.setLineNo(++line);//行号自增
            if (StringUtils.isNotBlank(x.getUnitPrice())) {
                allocateApplyOrderDetailCreateDTO.setUnitPrice(new BigDecimal(x.getUnitPrice()));
            }
            Features features = Features.newFeatures();
            if (x.getApplyDeviationReason() != null) {
                features.addFeature("applyDeviationReason", x.getApplyDeviationReason());
            }
            if (x.getAlgorithmSuggestQuantity() != null) {
                features.addFeature("algorithmSuggestQuantity", x.getAlgorithmSuggestQuantity());
            }
            if (x.getPlanSuggestQuantity() != null) {
                features.addFeature("planSuggestQuantity", x.getPlanSuggestQuantity());
            }
            if (x.getAdvanceApplyQuantity() != null) {
                features.addFeature("advanceApplyQuantity", x.getAdvanceApplyQuantity());
            }
            if (x.getDistributeRatio() != null) {
                features.addFeature("biz_unit_ratio", x.getDistributeRatio());
            }
            allocateApplyOrderDetailCreateDTO.setFeatures(features.toString());
            allocateApplyOrderDetailCreateDTO.setBizFeatures(features.toString());
            allocateApplyOrderDetailList.add(allocateApplyOrderDetailCreateDTO);
        }
        return allocateApplyOrderDetailList;
    }

    @Override
    @FacadeInvoker(value = "回复调拨预报单")
    public Result<Boolean> replyTransferForecastOrder(TransferForecastReplyRequest transferForecastReplyRequest) {
        String s = checkReplyTransferForecastOrder(transferForecastReplyRequest);

        if(s !=null){
            return Result.fail("10000",s);
        }
        QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
        queryAllocateApplyOrderRequest.setCode(transferForecastReplyRequest.getTransferForecastOrderCode());
        queryAllocateApplyOrderRequest.setBusinessType(transferForecastReplyRequest.getBusinessType());
        queryAllocateApplyOrderRequest.setFromSys(transferForecastReplyRequest.getFromSys());
        Result<AllocateApplyOrderDetailDTO> result = allocateApplyOrderReadService.queryAllocateApplyOrder(queryAllocateApplyOrderRequest);
        AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = result.getResult();
        if(allocateApplyOrderDetailDTO == null){
            return Result.fail("10001","预报单不存在");
        }
        if(allocateApplyOrderDetailDTO.getId() == null){
            return Result.fail("10001","预报单不存在");
        }
        String message = "";
        String errorCode = "";
        // 回复状态为待回复、部分回复、待总部回复、才可以回复
        if(!(ObjectUtil.equals(allocateApplyOrderDetailDTO.getStatus(),AllocateApplyOrderStatusEnum.WAIT_ANSWER.getCode())
                || ObjectUtil.equals(allocateApplyOrderDetailDTO.getStatus(),AllocateApplyOrderStatusEnum.PART_ANSWER.getCode())
                || ObjectUtil.equals(allocateApplyOrderDetailDTO.getStatus(),AllocateApplyOrderStatusEnum.HEADQUARTERS_REPLY.getCode()))){
            return Result.fail("10003","预报单预报单状态不合法");
        }
        // 不支持计划调拨预报单回复
        if(ObjectUtil.equals(allocateApplyOrderDetailDTO.getType(),AllocateOrderTypeEnum.PLAN.getType().toString()) ){
            return Result.fail("10003","不支持计划调拨预报单回复");
        }
        Map<String, TransferForecastReplyDetailRequest> replyDetailNewMap = transferForecastReplyRequest.getTransferForecastReplyDetailRequestList().stream()
                .collect(Collectors.toMap(TransferForecastReplyDetailRequest::getDetailNo, Function.identity(), (x1, x2) -> x2));
//        //仓库校验
//        WarehouseQueryResponse receiveDeliveryLogicWarehouse = getWarehouseInfoById(allocateApplyOrderDetailDTO.getReceiveWarehouseId());
        //发货仓code
        WarehouseQueryResponse deliveryLogicWarehouse = getWarehouseInfo(transferForecastReplyRequest.getDeliveryLogicWarehouseCode());
//        // 仓库校验
//        String wareHouseMessage = CheckUtil.checkWareHouse(Integer.parseInt(allocateApplyOrderDetailDTO.getType()), receiveDeliveryLogicWarehouse, deliveryLogicWarehouse);
        String wareHouse = CheckUtil.checkReplyWareHouse(deliveryLogicWarehouse);
        if(wareHouse != null){
            return Result.fail("10006",wareHouse);
        }

        // 同公司回复
        if(ObjectUtil.equals(allocateApplyOrderDetailDTO.getType(),AllocateOrderTypeEnum.SAME_COMPANY.getType().toString())){
            AllocateApplyOrderReplyDTO allocateApplyOrderReplyDTO = new AllocateApplyOrderReplyDTO();
            allocateApplyOrderReplyDTO.setFromSys(transferForecastReplyRequest.getFromSys());
            allocateApplyOrderReplyDTO.setBusinessType(transferForecastReplyRequest.getBusinessType());
            allocateApplyOrderReplyDTO.setCode(transferForecastReplyRequest.getTransferForecastOrderCode());
            allocateApplyOrderReplyDTO.setShipMethod(transferForecastReplyRequest.getShipMethodCode());
            WarehouseQueryResponse warehouseInfo = getWarehouseInfo(transferForecastReplyRequest.getDeliveryLogicWarehouseCode());
            allocateApplyOrderReplyDTO.setShipWarehouseId(Integer.valueOf(warehouseInfo.getId()));
            allocateApplyOrderReplyDTO.setId(allocateApplyOrderDetailDTO.getId());

            List<AllocateApplyOrderDetailCreateDTO> collect2= new ArrayList<>();
            for (AllocateApplyOrderGoodsDetailDTO goodsOld:allocateApplyOrderDetailDTO.getList()){
                TransferForecastReplyDetailRequest x = replyDetailNewMap.get(String.valueOf(goodsOld.getLineNo()));
                if (x == null) {
                    return Result.fail("10001", "未找到行号为:" + goodsOld.getLineNo() + "的调拨子单");
                }
                AllocateApplyOrderDetailCreateDTO allocateApplyOrderDetailCreateDTO = new AllocateApplyOrderDetailCreateDTO();
                int replyQuantity =0;
                if(goodsOld.getReplyQuantity() != null){
                    replyQuantity = goodsOld.getReplyQuantity();
                }
                int quantity = Integer.parseInt(x.getQuantity());
                if(quantity + replyQuantity >goodsOld.getApplyQuantity()){
                    return Result.fail("","回复数不能大于提报数");
                }
                allocateApplyOrderDetailCreateDTO.setDeliverQuantity(Integer.parseInt(x.getQuantity()));
                allocateApplyOrderDetailCreateDTO.setProductionTime(strToDate(x.getProductDate()));
                //allocateApplyOrderDetailCreateDTO.setIsClosed(Integer.parseInt(x.getShutDownFlag()));
                if (x.getShutDownFlag() != null) {
                    allocateApplyOrderDetailCreateDTO.setIsClosed(Integer.parseInt(x.getShutDownFlag()));
                    if ("0".equals(x.getShutDownFlag())) {
                        allocateApplyOrderDetailCreateDTO.setCloseReason(null);
                    } else if ("1".equals(x.getShutDownFlag())) {
                        allocateApplyOrderDetailCreateDTO.setDeliverQuantity(0);
                        allocateApplyOrderDetailCreateDTO.setCloseReason("19");// 19:关闭订单
                    }
                } else {
                    allocateApplyOrderDetailCreateDTO.setIsClosed(0);
                    allocateApplyOrderDetailCreateDTO.setCloseReason(null);
                }
                    /*// 0：正常
                    if (x.getShutDownFlag() != null && "0".equals(x.getShutDownFlag())) {
                        allocateApplyOrderDetailCreateDTO.setCloseReason(null);
                    }
                    // 1关闭
                    if (x.getShutDownFlag() != null && "1".equals(x.getShutDownFlag())) {
                        allocateApplyOrderDetailCreateDTO.setDeliverQuantity(0);
                        allocateApplyOrderDetailCreateDTO.setCloseReason("19");// 19:关闭订单
                    }*/
                allocateApplyOrderDetailCreateDTO.setOutLineNo(goodsOld.getOutLineNo());
                allocateApplyOrderDetailCreateDTO.setScItemId(goodsOld.getScItemId());
                allocateApplyOrderDetailCreateDTO.setGoodsId(goodsOld.getGoodsId());
                allocateApplyOrderDetailCreateDTO.setTitle(goodsOld.getTitle());
                allocateApplyOrderDetailCreateDTO.setStatus(goodsOld.getStatus());
                allocateApplyOrderDetailCreateDTO.setLineNo(goodsOld.getLineNo());
                allocateApplyOrderDetailCreateDTO.setApplyQuantity(goodsOld.getApplyQuantity());
                allocateApplyOrderDetailCreateDTO.setRemark(goodsOld.getRemark());
                allocateApplyOrderDetailCreateDTO.setUom(goodsOld.getUom());
                allocateApplyOrderDetailCreateDTO.setReplyQuantity(goodsOld.getReplyQuantity());
                allocateApplyOrderDetailCreateDTO.setThirdLineNo(goodsOld.getThirdLineNo());
                collect2.add(allocateApplyOrderDetailCreateDTO);
            }
            allocateApplyOrderReplyDTO.setList(collect2);
            log.info("TransferForecastOrderWriteService.replyTransferForecastOrder.allocateApplyOrderReplyDTO:{},data:{}", queryAllocateApplyOrderRequest.getCode(), JSON.toJSONString(queryAllocateApplyOrderRequest));
            Result<Object> objectResult = allocateApplyOrderWriteService.replyAllocateApplyOrder(allocateApplyOrderReplyDTO);
            message = objectResult.getMessage();
            errorCode = objectResult.getErrorCode();
            if(objectResult.isSuccess()){
                return Result.success(true);
            }
        }
        // 跨公司回复
        if(ObjectUtil.equals(allocateApplyOrderDetailDTO.getType(),AllocateOrderTypeEnum.CROSS_COMPANY.getType().toString())){
            if(!ObjectUtil.equals(allocateApplyOrderDetailDTO.getStatus(),AllocateApplyOrderStatusEnum.HEADQUARTERS_REPLY.getCode())){
                return Result.fail("","必须带待总部回复");
            }
            AllocateApplyOrderUpdateDTO allocateApplyOrderUpdateDTO = new AllocateApplyOrderUpdateDTO();
            allocateApplyOrderUpdateDTO.setId(allocateApplyOrderDetailDTO.getId());
            allocateApplyOrderUpdateDTO.setCode(allocateApplyOrderDetailDTO.getCode());
            allocateApplyOrderUpdateDTO.setOrderTime(strToDate(allocateApplyOrderDetailDTO.getOrderTime()));
            allocateApplyOrderUpdateDTO.setHopeDeliveryTime(strToDate(allocateApplyOrderDetailDTO.getHopeDeliveryTime()));
            allocateApplyOrderUpdateDTO.setType(String.valueOf(allocateApplyOrderDetailDTO.getType()));
            allocateApplyOrderUpdateDTO.setBusinessType(allocateApplyOrderDetailDTO.getBusinessType());
            allocateApplyOrderUpdateDTO.setFromSys(allocateApplyOrderDetailDTO.getFromSys());
            allocateApplyOrderUpdateDTO.setShipWarehouseId(deliveryLogicWarehouse.getId());
            allocateApplyOrderUpdateDTO.setIsDTC(false);
            List<AllocateApplyOrderGoodsDetailDTO> list = allocateApplyOrderDetailDTO.getList();
            if(CollectionUtil.isEmpty(list)){
                throw new FacadeException("暂无货品信息");
            }
            List<AllocateApplyOrderDetailCreateDTO> collect = new ArrayList<>();
            for(AllocateApplyOrderGoodsDetailDTO goodsOld:allocateApplyOrderDetailDTO.getList()){
                TransferForecastReplyDetailRequest newReplay = replyDetailNewMap.get(String.valueOf(goodsOld.getLineNo()));
                if (newReplay == null) {
                    return Result.fail("10001", "未找到行号为:" + goodsOld.getLineNo() + "的调拨子单");
                }
                AllocateApplyOrderDetailCreateDTO allocateApplyOrderDetailCreateDTO = new AllocateApplyOrderDetailCreateDTO();
                int replyQuantity =0;
                if(goodsOld.getReplyQuantity() != null){
                    replyQuantity = goodsOld.getReplyQuantity();
                }
                int quantity = Integer.parseInt(newReplay.getQuantity());
                int applyQuantity = goodsOld.getApplyQuantity();
                if(quantity + replyQuantity >applyQuantity){
                    return Result.fail("","回复数不能大于提报数");
                }
                allocateApplyOrderDetailCreateDTO.setDeliverQuantity(Integer.parseInt(newReplay.getQuantity()));
                allocateApplyOrderDetailCreateDTO.setProductionTime(strToDate(newReplay.getProductDate()));
                //allocateApplyOrderDetailCreateDTO.setIsClosed(Integer.parseInt(newReplay.getShutDownFlag()));
                if (newReplay.getShutDownFlag() != null) {
                    allocateApplyOrderDetailCreateDTO.setIsClosed(Integer.parseInt(newReplay.getShutDownFlag()));
                    if ("0".equals(newReplay.getShutDownFlag())) {
                        allocateApplyOrderDetailCreateDTO.setCloseReason(null);
                    } else if ("1".equals(newReplay.getShutDownFlag())) {
                        allocateApplyOrderDetailCreateDTO.setDeliverQuantity(0);
                        allocateApplyOrderDetailCreateDTO.setCloseReason("19");// 19:关闭订单
                    }
                } else {
                    allocateApplyOrderDetailCreateDTO.setIsClosed(0);
                    allocateApplyOrderDetailCreateDTO.setCloseReason(null);
                }
                    /*// 0：正常
                    if (newReplay.getShutDownFlag() != null && "0".equals(newReplay.getShutDownFlag() )) {
                        allocateApplyOrderDetailCreateDTO.setCloseReason(null);
                    }
                    // 1关闭
                    if (newReplay.getShutDownFlag() != null &&  "1".equals(newReplay.getShutDownFlag())) {
                        allocateApplyOrderDetailCreateDTO.setDeliverQuantity(0);
                        allocateApplyOrderDetailCreateDTO.setCloseReason("19");// 19:关闭订单
                    }*/
                allocateApplyOrderDetailCreateDTO.setOutLineNo(goodsOld.getOutLineNo());
                allocateApplyOrderDetailCreateDTO.setScItemId(goodsOld.getScItemId());
                allocateApplyOrderDetailCreateDTO.setGoodsId(goodsOld.getGoodsId());
                allocateApplyOrderDetailCreateDTO.setTitle(goodsOld.getTitle());
                allocateApplyOrderDetailCreateDTO.setStatus(goodsOld.getStatus());
                allocateApplyOrderDetailCreateDTO.setLineNo(goodsOld.getLineNo());
                allocateApplyOrderDetailCreateDTO.setApplyQuantity(goodsOld.getApplyQuantity());
                allocateApplyOrderDetailCreateDTO.setRemark(goodsOld.getRemark());
                allocateApplyOrderDetailCreateDTO.setUom(goodsOld.getUom());
                allocateApplyOrderDetailCreateDTO.setReplyQuantity(goodsOld.getReplyQuantity());
                allocateApplyOrderDetailCreateDTO.setThirdLineNo(goodsOld.getThirdLineNo());
                collect.add(allocateApplyOrderDetailCreateDTO);
            }
            allocateApplyOrderUpdateDTO.setList(collect);
            allocateApplyOrderUpdateDTO.setFromThirdParty(FROM_THIRD_PARTY);
            Result<AllocateApplyOrderDetailDTO> result2 = allocateApplyOrderWriteService.submitAllocateApplyOrder(allocateApplyOrderUpdateDTO);
            message = result2.getMessage();
            errorCode = result2.getErrorCode();
            if(result2.isSuccess()){
                return Result.success(true);
            }
        }
        return Result.fail(errorCode,message);
    }


    private String checkReplyTransferForecastOrder(TransferForecastReplyRequest replyRequest) {
        if(StringUtils.isBlank(replyRequest.getFromSys())){
            return "系统来源不能为空";
        }
        if(replyRequest.getFromSys().length() >32){
            return "系统来源字段长度不能大于32";
        }
        if(StringUtils.isBlank(replyRequest.getBusinessType()) ){
            return "业态不能为空";
        }
        if(replyRequest.getBusinessType().length() >32 ){
            return "业态字段长度不能大于32";
        }
        if(StringUtils.isBlank(replyRequest.getTransferForecastOrderCode())){
            return "调拨预报单号不能为空";
        }
        if(replyRequest.getTransferForecastOrderCode().length() > 32){
            return "调拨预报单号字段长度不能大于32";
        }
        if(StringUtils.isBlank(replyRequest.getShipMethodCode())){
            return "运输方式编码不能为空";
        }
        if(replyRequest.getShipMethodCode().length() >32){
            return "运输方式编码字段长度不能大于32";
        }
        if(StringUtils.isBlank(replyRequest.getDeliveryLogicWarehouseCode())){
            return "发货逻辑仓库不能为空";
        }
        if(replyRequest.getDeliveryLogicWarehouseCode().length() >32){
            return "发货逻辑仓库字段长度不能大于32";
        }
        if(CollectionUtil.isEmpty(replyRequest.getTransferForecastReplyDetailRequestList())){
            return "调拨预报单回复详情不能为空";
        }

        Set<String> detailNoSet = Sets.newHashSet();
        for(TransferForecastReplyDetailRequest x:replyRequest.getTransferForecastReplyDetailRequestList()){
            if(x.getQuantity() == null){
                return "发货数量回复不能为空";
            }
            if(StringUtils.isBlank(x.getDetailNo() )){
                return "调拨单行号不能为空";
            }
            if(x.getDetailNo().length() >32){
                return "调拨单行号字段长度不能大于32";
            }
            if(StringUtils.isBlank(x.getProductDate() )){
                return "生产日期不能为空";
            }
            if(x.getProductDate().length() != 19 || !CheckUtil.isLegalDate(x.getProductDate())){
                return "生产日期格式不正确";
            }
            if(StringUtils.isNotEmpty(x.getShutDownFlag())){
                if(x.getShutDownFlag().length() >2){
                    return "是否关闭字段长度不能大于2";
                }
                if(!("0".equals(x.getShutDownFlag()) || "1".equals(x.getShutDownFlag()))){
                    return "是否关闭不合法";
                }
            }else {
                x.setShutDownFlag("0");
            }
            if(StringUtils.isBlank(x.getQuantity())){
                return "数量不能为空";
            }
            if(x.getQuantity().length() > 10){
                return "数量长度不能大于10位";
            }
            if(!StringUtils.isNumeric(x.getQuantity())){
                return "数量输入非法";
            }
            detailNoSet.add(x.getDetailNo());
        }
        if (detailNoSet.size() != replyRequest.getTransferForecastReplyDetailRequestList().size()) {
            return "调拨单行号不能重复";
        }
        String s = checkFromSysAndBusinessType(replyRequest.getFromSys(), replyRequest.getBusinessType());
        if(s != null){
            return s;
        }
        return null;
    }

    @Override
    @FacadeInvoker(value = "取消调拨预报单")
    public Result<Boolean> cancelTransferForecastOrder(TransferForecastOrderCancelRequest transferForecastOrderCancelRequest) {

        String message = checkCancelTransferForecastOrder(transferForecastOrderCancelRequest);
        if(message !=null){
            return Result.fail("10000", message);
        }
        QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
        queryAllocateApplyOrderRequest.setCode(transferForecastOrderCancelRequest.getTransferForecastOrderCode());
        queryAllocateApplyOrderRequest.setBusinessType(transferForecastOrderCancelRequest.getBusinessType());
        queryAllocateApplyOrderRequest.setFromSys(transferForecastOrderCancelRequest.getFromSys());
        Result<AllocateApplyOrderDetailDTO> result = allocateApplyOrderReadService.queryAllocateApplyOrder(queryAllocateApplyOrderRequest);
        if(result.getResult() == null){
            return Result.fail("10003", "草稿_待推送状态下允许取消");
        }
        if(result.getResult().getId() == null){
            return Result.fail("10003", "草稿_待推送状态下允许取消");
        }
        AllocateApplyOrderDetailDTO applyOrderDetailDTO = result.getResult();
        if (!(AllocateApplyOrderStatusEnum.DRAFT.getCode().equals(applyOrderDetailDTO.getStatus())
                || AllocateApplyOrderStatusEnum.TO_BE_SUBMITTED.getCode().equals(applyOrderDetailDTO.getStatus()))) {
            return Result.fail("10001", "状态不合法");
        }
        CancelAllocateApplyOrderRequest cancelAllocateApplyOrderRequest = new CancelAllocateApplyOrderRequest();
        cancelAllocateApplyOrderRequest.setBusinessType(transferForecastOrderCancelRequest.getBusinessType());
        cancelAllocateApplyOrderRequest.setFromSys(transferForecastOrderCancelRequest.getFromSys());
        cancelAllocateApplyOrderRequest.setCode(transferForecastOrderCancelRequest.getTransferForecastOrderCode());
        cancelAllocateApplyOrderRequest.setUpdater(transferForecastOrderCancelRequest.getUpdater());
        return allocateApplyOrderWriteService.cancelAllocateApplyOrder(cancelAllocateApplyOrderRequest);
    }

    private String  checkCancelTransferForecastOrder(TransferForecastOrderCancelRequest transferForecastOrderCancelRequest) {

        if(StringUtils.isBlank(transferForecastOrderCancelRequest.getFromSys() )){
            return "系统来源不能为空";
        }
        if(transferForecastOrderCancelRequest.getFromSys().length() >32){
            return "系统来源字段长度不能大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderCancelRequest.getBusinessType())){
            return "业态不能为空";
        }
        if(transferForecastOrderCancelRequest.getBusinessType().length() >32){
            return "业态字段长度不能大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderCancelRequest.getTransferForecastOrderCode())){
            return "调拨预报单号不能为空";
        }
        if(transferForecastOrderCancelRequest.getTransferForecastOrderCode().length() >32 ){
            return "调拨预报单号字段长度不能大于32";
        }
        String s = checkFromSysAndBusinessType(transferForecastOrderCancelRequest.getFromSys(), transferForecastOrderCancelRequest.getBusinessType());
        if(s != null){
            return s;
        }
        return null;
    }

    @Override
    @FacadeInvoker(value = "调拨预报单驳回")
    public Result<Boolean> rejectTransferForecastOrder(TransferForecastOrderRejectRequest transferForecastOrderRejectRequest) {
        String message = checkRejectTransferForecastOrder(transferForecastOrderRejectRequest);
        if(message != null){
            return Result.fail("10000", message);
        }
        Result<AllocateApplyOrderDetailDTO> result = getAllocateApplyOrderDetailDTO(transferForecastOrderRejectRequest.getTransferForecastOrderCode(), transferForecastOrderRejectRequest.getFromSys(), transferForecastOrderRejectRequest.getBusinessType());
        if(result.getResult() == null){
            return Result.fail("10000", "该预报单不存在");
        }
        AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = result.getResult();
        if(allocateApplyOrderDetailDTO.getId() == null){
            return Result.fail(null, "预报单不存在");
        }
        // 驳回，只支持待回复、部分回复、待总部回复、待发货方回复
        if (!(AllocateApplyOrderStatusEnum.WAIT_ANSWER.getCode().equals(allocateApplyOrderDetailDTO.getStatus())
                || AllocateApplyOrderStatusEnum.PART_ANSWER.getCode().equals(allocateApplyOrderDetailDTO.getStatus())
                || AllocateApplyOrderStatusEnum.HEADQUARTERS_REPLY.getCode().equals(allocateApplyOrderDetailDTO.getStatus())
                || AllocateApplyOrderStatusEnum.SHIPPER_REPLY.getCode().equals(allocateApplyOrderDetailDTO.getStatus()))) {
            return Result.fail("10003", "预报单状态不合法");
        }


        if(EqualsUtil.areEqual(allocateApplyOrderDetailDTO.getType(), DocumentTypeEnum.PLANNED_ALLOCATION.getCode())){
            return Result.fail(null, "不支持计划单驳回");
        }
        RejectAllocateApplyOrderRequest rejectAllocateApplyOrderRequest = new RejectAllocateApplyOrderRequest();
        rejectAllocateApplyOrderRequest.setFromSys(transferForecastOrderRejectRequest.getFromSys());
        rejectAllocateApplyOrderRequest.setBusinessType(transferForecastOrderRejectRequest.getBusinessType());
        rejectAllocateApplyOrderRequest.setCode(transferForecastOrderRejectRequest.getTransferForecastOrderCode());
        return allocateApplyOrderWriteService.rejectAllocateApplyOrder(rejectAllocateApplyOrderRequest);
    }
    private String checkRejectTransferForecastOrder(TransferForecastOrderRejectRequest reject) {
        if(StringUtils.isBlank(reject.getFromSys())){
            return "系统来源不能为空";
        }
        if(reject.getFromSys().length() >32){
            return "系统来源字段长度不能大于32";
        }
        if(StringUtils.isBlank(reject.getBusinessType() )){
            return "业态不能为空";
        }
        if(reject.getBusinessType().length() >32){
            return "业态字段长度不能大于32";
        }
        if(StringUtils.isBlank(reject.getTransferForecastOrderCode())){
            return "调拨预报单号不能为空";
        }
        if(reject.getTransferForecastOrderCode().length() >32 ){
            return "调拨预报单号字段长度不能大于32";
        }
        String s = checkFromSysAndBusinessType(reject.getFromSys(), reject.getBusinessType());
        if(s != null){
            return s;
        }
        return null;
    }


    private Result<AllocateApplyOrderDetailDTO> getAllocateApplyOrderDetailDTO(String code ,String fromSys,String businessType){
        QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
        queryAllocateApplyOrderRequest.setCode(code);
        queryAllocateApplyOrderRequest.setFromSys(fromSys);
        queryAllocateApplyOrderRequest.setBusinessType(businessType);

        Result<AllocateApplyOrderDetailDTO> result = allocateApplyOrderReadService.queryAllocateApplyOrder(queryAllocateApplyOrderRequest);
        return result;
    }
    @Override
    @FacadeInvoker(value = "提交调拨预报单")
    public Result<Boolean> submitTransferForecastOrder(TransferForecastOrderSubmitRequest transferForecastOrderSubmitRequest) {

        String message = checkSubmitTransferForecastOrder(transferForecastOrderSubmitRequest);
        if(message != null){
            return Result.fail("10000", message);
        }
        LoadAllocateApplyOrderByCodeV2Request queryAllocateApplyOrderRequest = new LoadAllocateApplyOrderByCodeV2Request();
        queryAllocateApplyOrderRequest.setCode(transferForecastOrderSubmitRequest.getTransferForecastOrderCode());
        AllocateApplyOrder allocateApplyOrder = allocateApplyOrderService.loadAllocateApplyOrderByCodeV2(queryAllocateApplyOrderRequest);
        if(allocateApplyOrder == null){
            return Result.fail("10001", "预报单不存在");
        }
        if (!(AllocateApplyOrderStatusEnum.DRAFT.getCode().equals(allocateApplyOrder.getStatus())
                || AllocateApplyOrderStatusEnum.TO_BE_SUBMITTED.getCode().equals(allocateApplyOrder.getStatus()))) {
            return Result.fail("10003", "预报单状态不合法");
        }

        List<AllocateApplyOrderGoodsDetailDTO> list = allocateApplyOrderDetailReadRepository.loadDetailByOrderId(allocateApplyOrder.getId());
        if(CollectionUtil.isEmpty(list)){
            return Result.fail("10001", "预报单子单不存在");
        }
        // 拼接提交调拨预报单参数
        AllocateApplyOrderUpdateDTO allocateApplyOrderUpdateDTO = getAllocateApplyOrderUpdateDTO(allocateApplyOrder,list);
//        allocateApplyOrderUpdateDTO.setOperator(transferForecastOrderSubmitRequest.getUpdater());
        allocateApplyOrderUpdateDTO.setModifierName(transferForecastOrderSubmitRequest.getUpdater());
        allocateApplyOrderUpdateDTO.setFromThirdParty(FROM_THIRD_PARTY);
        Result<AllocateApplyOrderDetailDTO> result =
                allocateApplyOrderWriteService.submitAllocateApplyOrder(allocateApplyOrderUpdateDTO);

        if(result.getResult() == null){
            return Result.fail(result.getErrorCode(), result.getMessage());
        }
        return Result.success(true);
    }

    /**
     * 根据调拨预报单code查询调拨单详情，拼接提交数据
     * @return dto
     */
    private AllocateApplyOrderUpdateDTO getAllocateApplyOrderUpdateDTO(AllocateApplyOrder result,List<AllocateApplyOrderGoodsDetailDTO> list){
        AllocateApplyOrderUpdateDTO allocateApplyOrderUpdateDTO = new AllocateApplyOrderUpdateDTO();
        allocateApplyOrderUpdateDTO.setId(result.getId());
        allocateApplyOrderUpdateDTO.setCode(result.getCode());
        allocateApplyOrderUpdateDTO.setOrderTime(result.getOrderTime());
        allocateApplyOrderUpdateDTO.setHopeDeliveryTime(result.getHopeDeliveryTime());
        allocateApplyOrderUpdateDTO.setType(String.valueOf(result.getType()));
        allocateApplyOrderUpdateDTO.setBusinessType(result.getBusinessType());
        allocateApplyOrderUpdateDTO.setFromSys(result.getFromSys());
        allocateApplyOrderUpdateDTO.setIsDTC(false);
        List<AllocateApplyOrderDetailCreateDTO> collect = list.stream().map(x -> {
            AllocateApplyOrderDetailCreateDTO allocateApplyOrderDetailCreateDTO = new AllocateApplyOrderDetailCreateDTO();
            allocateApplyOrderDetailCreateDTO.setAllocateApplyOrderId(Math.toIntExact(result.getId()));
            allocateApplyOrderDetailCreateDTO.setGoodsId(x.getGoodsId());
            allocateApplyOrderDetailCreateDTO.setScItemId(x.getScItemId());
            allocateApplyOrderDetailCreateDTO.setTitle(x.getTitle());
            allocateApplyOrderDetailCreateDTO.setApplyQuantity(x.getApplyQuantity());
            allocateApplyOrderDetailCreateDTO.setUom(x.getUom());
            allocateApplyOrderDetailCreateDTO.setRemark(x.getRemark());
            allocateApplyOrderDetailCreateDTO.setThirdLineNo(x.getThirdLineNo());
            allocateApplyOrderDetailCreateDTO.setLineNo(x.getLineNo());
            allocateApplyOrderDetailCreateDTO.setFeatures(x.getFeatures());
            allocateApplyOrderDetailCreateDTO.setBizFeatures(x.getBizFeatures());
            return allocateApplyOrderDetailCreateDTO;
        }).collect(Collectors.toList());
        allocateApplyOrderUpdateDTO.setList(collect);

        return allocateApplyOrderUpdateDTO;
    }

    private Date strToDate(String strDae) {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = null;
        try {
            parse = df.parse(strDae);
        } catch (ParseException e) {
            throw new FacadeException("时间格式转换异常");
        }
        return parse;
    }


    private String checkSubmitTransferForecastOrder(TransferForecastOrderSubmitRequest transferForecastOrderSubmitRequest) {
        if(StringUtils.isBlank(transferForecastOrderSubmitRequest.getFromSys() )){
            return "系统来源不能为空";
        }
        if(transferForecastOrderSubmitRequest.getFromSys().length() >32){
            return "系统来源字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderSubmitRequest.getBusinessType())){
            return "业态不能为空";
        }
        if(transferForecastOrderSubmitRequest.getBusinessType().length() >32){
            return "业态字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderSubmitRequest.getTransferForecastOrderCode())){
            return "调拨预报单号不能为空";
        }
        if(transferForecastOrderSubmitRequest.getTransferForecastOrderCode().length() >32){
            return "调拨预报单号字段长度大于32";
        }
        String s = checkFromSysAndBusinessType(transferForecastOrderSubmitRequest.getFromSys(), transferForecastOrderSubmitRequest.getBusinessType());
        if(s != null){
            return s;
        }
        return null;
    }

    @Override
    @FacadeInvoker(value = "调拨预报订单待发货方确认")
    public Result<Boolean> confirmTransferForecastOrder(TransferForecastOrderConfirmRequest transferForecastOrderConfirmRequest){
        String message = checkConfirmTransferForecastOrder(transferForecastOrderConfirmRequest);
        if(message !=null){
            return Result.fail("10000",message);
        }
        QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
        queryAllocateApplyOrderRequest.setCode(transferForecastOrderConfirmRequest.getTransferForecastOrderCode());
        queryAllocateApplyOrderRequest.setBusinessType(transferForecastOrderConfirmRequest.getBusinessType());
        queryAllocateApplyOrderRequest.setFromSys(transferForecastOrderConfirmRequest.getFromSys());
        log.info("queryAllocateApplyOrder,request:{}", JSON.toJSON(transferForecastOrderConfirmRequest));
        Result<AllocateApplyOrderDetailDTO> result = allocateApplyOrderReadService.queryAllocateApplyOrder(queryAllocateApplyOrderRequest);
        log.info("queryAllocateApplyOrder,result:{}", JSON.toJSON(result));
        if(result.getResult() == null){
            return Result.fail("10001","预报单不存在");
        }
        AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = result.getResult();

        if(allocateApplyOrderDetailDTO.getType() == null || allocateApplyOrderDetailDTO.getStatus() == null){
            return Result.fail("10003","仅支持待发货方回复的跨公司调拨预报订单");
        }
        if(!EqualsUtil.areEqual(allocateApplyOrderDetailDTO.getStatus(), AllocateApplyOrderStatusEnum.SHIPPER_REPLY.getCode())){
            return Result.fail("10003","仅支待发货方回复的调拨预报订单");
        }
        if(!EqualsUtil.areEqual(allocateApplyOrderDetailDTO.getType(), DocumentTypeEnum.CROSS_COMPANY_BORROW_GOODS_ALLOCATION.getCode())){
            return Result.fail("10003","仅支持跨公司调拨预报订单");
        }
        AllocateApplyOrderReplyDTO allocateApplyOrderReplyDTO = new AllocateApplyOrderReplyDTO();
        allocateApplyOrderReplyDTO.setFromSys(allocateApplyOrderDetailDTO.getFromSys());
        allocateApplyOrderReplyDTO.setBusinessType(allocateApplyOrderDetailDTO.getBusinessType());
        allocateApplyOrderReplyDTO.setCode(allocateApplyOrderDetailDTO.getCode());
        allocateApplyOrderReplyDTO.setShipMethod(allocateApplyOrderDetailDTO.getShipMethod());
        allocateApplyOrderReplyDTO.setShipWarehouseId(Integer.parseInt(allocateApplyOrderDetailDTO.getShipWarehouseId()));
        allocateApplyOrderReplyDTO.setId(allocateApplyOrderDetailDTO.getId());

        List<AllocateApplyOrderDetailCreateDTO> collect2 = new ArrayList<>();
        for (AllocateApplyOrderGoodsDetailDTO goodsOld:allocateApplyOrderDetailDTO.getList()){
            AllocateApplyOrderDetailCreateDTO allocateApplyOrderDetailCreateDTO = new AllocateApplyOrderDetailCreateDTO();
            if(StringUtils.isNotBlank(goodsOld.getProductionTime())){
                allocateApplyOrderDetailCreateDTO.setProductionTime(strToDate(goodsOld.getProductionTime()));
            }
            allocateApplyOrderDetailCreateDTO.setIsClosed(goodsOld.getIsClosed());
            allocateApplyOrderDetailCreateDTO.setCloseReason(goodsOld.getCloseReason());
            allocateApplyOrderDetailCreateDTO.setDeliverQuantity(goodsOld.getDeliverQuantity());
            allocateApplyOrderDetailCreateDTO.setOutLineNo(goodsOld.getOutLineNo());
            allocateApplyOrderDetailCreateDTO.setScItemId(goodsOld.getScItemId());
            allocateApplyOrderDetailCreateDTO.setGoodsId(goodsOld.getGoodsId());
            allocateApplyOrderDetailCreateDTO.setTitle(goodsOld.getTitle());
            allocateApplyOrderDetailCreateDTO.setStatus(goodsOld.getStatus());
            allocateApplyOrderDetailCreateDTO.setLineNo(goodsOld.getLineNo());
            allocateApplyOrderDetailCreateDTO.setApplyQuantity(goodsOld.getApplyQuantity());
            allocateApplyOrderDetailCreateDTO.setRemark(goodsOld.getRemark());
            allocateApplyOrderDetailCreateDTO.setUom(goodsOld.getUom());
            allocateApplyOrderDetailCreateDTO.setReplyQuantity(goodsOld.getReplyQuantity());
            allocateApplyOrderDetailCreateDTO.setThirdLineNo(goodsOld.getThirdLineNo());
            collect2.add(allocateApplyOrderDetailCreateDTO);
        }
        allocateApplyOrderReplyDTO.setList(collect2);
        log.info("TransferForecastOrderWriteService_confirmTransferForecastOrder,replyAllocateApplyOrder,request:{}", JSON.toJSON(allocateApplyOrderReplyDTO));
        Result<Object> objectResult = allocateApplyOrderWriteService.replyAllocateApplyOrder(allocateApplyOrderReplyDTO);
        if(objectResult.isSuccess()){
            return Result.success(true);
        }
        return Result.fail(objectResult.getErrorCode(),objectResult.getMessage());
    }

    @FacadeInvoker(value = "预报单更新features")
    @Override
    public Result<Void> updateFeatures(FeaturesUpdateRequest featuresUpdateRequest) {
        log.info("TransferForecastOrderWriteServiceImpl_updateFeatures_request:{}",JSON.toJSONString(featuresUpdateRequest));
        if (featuresUpdateRequest == null || StringUtils.isAllBlank(featuresUpdateRequest.getMainOrderCode(),featuresUpdateRequest.getMainOrderId())){
            log.error("TransferForecastOrderWriteServiceImpl_updateFeatures_error,empty_code");
            return Result.success(null);
        }
        try(RedisLock lock = new RedisLock(BcOrderConstants.REDIS_CACHE_CODE(),UPDATE_FEATURES + (StringUtils.isBlank(featuresUpdateRequest.getMainOrderCode()) ?
                featuresUpdateRequest.getMainOrderId() : featuresUpdateRequest.getMainOrderCode()),
                5 * 60 * 1000, 10 * 60 * 1000)){
            if (!lock.lock()){
                throw new FacadeException("OTS-03-005-00-15-096");
            }
            Map<String, String> mainToUpdateMap = MapUtils.emptyIfNull(featuresUpdateRequest.getMainBizFeaturesToUpdate());
            Map<String, String> mainToDeleteMap = MapUtils.emptyIfNull(featuresUpdateRequest.getMainBizFeaturesToDelete());
            AllocateApplyOrderLoadListRequest allocateApplyOrderLoadListRequest = new AllocateApplyOrderLoadListRequest();
            if (StringUtils.isNotBlank(featuresUpdateRequest.getMainOrderId())){
                allocateApplyOrderLoadListRequest.setId(Long.parseLong(featuresUpdateRequest.getMainOrderId()));
            }else if (StringUtils.isNotBlank(featuresUpdateRequest.getMainOrderCode())){
                allocateApplyOrderLoadListRequest.setCode(featuresUpdateRequest.getMainOrderCode());
            }
            Result<List<AllocateApplyOrder>> listResult = allocateApplyOrderService.loadAllocateApplyOrderList(allocateApplyOrderLoadListRequest);
            if (listResult == null || CollectionUtils.isEmpty(listResult.getResult())){
                throw new FacadeException("OTS-03-005-00-15-230","查询调拨预报单");
            }
            AllocateApplyOrder applyOrder = listResult.getResult().get(0);
            if (MapUtils.isNotEmpty(mainToUpdateMap) || MapUtils.isNotEmpty(mainToDeleteMap)){
                Map<String, String> bizFeatures = FeatureUtil.fromString(applyOrder.getBizFeatures());
                if (MapUtils.isNotEmpty(mainToUpdateMap)){
                    bizFeatures.putAll(mainToUpdateMap);
                }
                if (MapUtils.isNotEmpty(mainToDeleteMap)){
                    mainToDeleteMap.keySet().forEach(bizFeatures::remove);
                }
                UpdateFeaturesRequest updateFeaturesRequest = new UpdateFeaturesRequest();
                updateFeaturesRequest.setMainOrderCode(featuresUpdateRequest.getMainOrderCode());
                updateFeaturesRequest.setBizFeatures(FeatureUtil.toString(bizFeatures));
                allocateApplyOrderService.updateFeatures(updateFeaturesRequest);
            }
            Nullable.stream(featuresUpdateRequest.getSubList()).forEach(subFeaturesRequest -> {
                Map<String, String> subToUpdateMap = MapUtils.emptyIfNull(subFeaturesRequest.getSubBizFeaturesToUpdate());
                if (MapUtils.isNotEmpty(subToUpdateMap) || CollectionUtils.isNotEmpty(subFeaturesRequest.getSubBizFeaturesToDelete())){
                    AllocateApplyOrderDetailLoadListRequest loadListRequest = new AllocateApplyOrderDetailLoadListRequest();
                    loadListRequest.setAllocateApplyOrderId(applyOrder.getId().intValue());
                    loadListRequest.setLineNo(Integer.parseInt(subFeaturesRequest.getBizSubOrderLineNo()));
                    Result<List<AllocateApplyOrderDetail>> detailList = allocateApplyOrderDetailService.loadAllocateApplyOrderDetailList(loadListRequest);
                    if (detailList == null || CollectionUtils.isEmpty(detailList.getResult())){
                        throw new FacadeException("OTS-03-005-00-15-230","查询调拨预报单明细");
                    }
                    AllocateApplyOrderDetail detail = detailList.getResult().get(0);
                    Map<String, String> bizFeatures = FeatureUtil.fromString(detail.getBizFeatures());
                    if (MapUtils.isNotEmpty(subToUpdateMap)){
                        bizFeatures.putAll(subToUpdateMap);
                    }
                    Nullable.stream(subFeaturesRequest.getSubBizFeaturesToDelete()).forEach(bizFeatures::remove);
                    com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.dto.UpdateFeaturesRequest featuresRequest =
                            new com.epoch.app.crunifiedinventory.domain.allocateapplyorderdetail.dto.UpdateFeaturesRequest();
                    featuresRequest.setMainOrderId(applyOrder.getId().toString());
                    featuresRequest.setBizFeatures(FeatureUtil.toString(bizFeatures));
                    featuresRequest.setLineNo(Integer.parseInt(subFeaturesRequest.getBizSubOrderLineNo()));
                    allocateApplyOrderDetailService.updateFeatures(featuresRequest);
                }
            });

        }

        return Result.success(null);
    }

    @Override
    @FacadeInvoker(value = "调拨预报单创建，应用使用")
    public Result<TransferForecastOrderCreateResponse> createTransferForecastOrderV2(TransferForecastOrderCreateRequest transferForecastOrderCreateRequest) {
        log.info("createTransferForecastOrder4APP|request={}",JSON.toJSONString(transferForecastOrderCreateRequest));
        StopWatch stopWatch = new StopWatch("调拨预报单创建V2");
        stopWatch.start("check");
        String message = checkCreateTransferForecastOrderV2(transferForecastOrderCreateRequest);
        stopWatch.stop();
        if (message !=null) {
            return Result.fail("10000",message);
        }
        String key =transferForecastOrderCreateRequest.getBusinessType()+"_"
                +transferForecastOrderCreateRequest.getFromSys()+"_"
                +transferForecastOrderCreateRequest.getRequestId()+"_"
                +transferForecastOrderCreateRequest.getThirdAllocateApplyOrderId();
        //请求幂等
        try (RedisLock lock = new RedisLock(BcOrderConstants.REDIS_CACHE_CODE(),
                "createTransferForecastOrder_" + key,
                5000,10000)){
            if (!lock.lock()){
                return Result.fail("10009","不能重复提交");
            }
            stopWatch.start("idempotentCheck");
            Result<List<AllocateApplyOrder>> idempotentResult = allocateApplyOrderService.loadAllocateApplyOrderList(AllocateApplyOrderLoadListRequest
                    .newAllocateApplyOrderLoadListRequestBuilder()
                    .fromSys(transferForecastOrderCreateRequest.getFromSys())
                    .requestId(transferForecastOrderCreateRequest.getRequestId()).build());
            stopWatch.stop();
            if (CollectionUtils.isNotEmpty(idempotentResult.getResult())) {
                return Result.fail("10002","单据已存在，请勿重复请求");
            }
            List<String> scItemCodeList = transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList()
                    .stream().map(TransferForecastOrderCreateDetail::getGoodsCode).distinct().collect(Collectors.toList());
            stopWatch.start("getScItemInfoList");
            Map<String, ScItemResponse> scItemInDOfoMap = getScItemInfoList(scItemCodeList);
            stopWatch.stop();
            if(scItemInDOfoMap == null){
                return Result.fail("10001","货品不存在");
            }
            if(scItemCodeList.size() > scItemInDOfoMap.values().size()){
                List<String> collect = scItemInDOfoMap.values().stream().map(ScItemResponse::getOuterId).collect(Collectors.toList());
                scItemCodeList.removeAll(collect);
                return Result.fail("10001","货品不存在: " + JSON.toJSONString(scItemCodeList));
            }
            stopWatch.start("checkScItemTypeAndStatus");
            String checkScItemTypeAndStatus = CheckUtil.getCheckScItemTypeAndStatus(scItemInDOfoMap);
            stopWatch.stop();
            if(checkScItemTypeAndStatus !=null){
                return Result.fail("10001",checkScItemTypeAndStatus);
            }
            //货品单位
            transferForecastOrderCreateRequest.getTransferForecastOrderCreateDetailList().forEach(detail -> {
                ScItemResponse scItemResponse = scItemInDOfoMap.get(detail.getGoodsCode());
                if (scItemResponse != null && MapUtils.isNotEmpty(scItemResponse.getFeatures())) {
                    detail.setUnit(MapUtils.getString(scItemResponse.getFeatures(), "unitName"));
                }
            });

            // 仓库校验
            stopWatch.start("checkWareHouse");
            WarehouseQueryResponse receiveLogicWarehouse = getWarehouseInfo(transferForecastOrderCreateRequest.getReceiveLogicWarehouseCode());
            WarehouseQueryResponse shipLogicWarehouseId = getWarehouseInfo(transferForecastOrderCreateRequest.getDeliveryLogicWarehouseCode());
            stopWatch.stop();
            if (!Boolean.TRUE.equals(transferForecastOrderCreateRequest.getIsAppCreate())) {
                String wareHouseMessage = CheckUtil.checkWareHouse(Integer.parseInt(transferForecastOrderCreateRequest.getTransferForecastOrderType()), receiveLogicWarehouse, shipLogicWarehouseId);
                if(wareHouseMessage != null){
                    return Result.fail("10006",wareHouseMessage);
                }
            }
            AllocateApplyOrderCreateDTO allocateApplyOrderCreateDTO = convertAllocateApplyOrderCreateDTO(transferForecastOrderCreateRequest,receiveLogicWarehouse,shipLogicWarehouseId);
            // 设置features，业务单元，销售组织编码
            allocateApplyOrderCreateDTO.setFeatures(getFeatures4App(receiveLogicWarehouse, shipLogicWarehouseId, transferForecastOrderCreateRequest));

            log.info("createTransferForecastOrder_createAllocateApplyOrder,request:{}",JSON.toJSON(allocateApplyOrderCreateDTO));
            stopWatch.start("createAllocateApplyOrder");
            Result<AllocateApplyOrderDetailDTO> allocateApplyOrder = allocateApplyOrderWriteService.createAllocateApplyOrder(allocateApplyOrderCreateDTO);
            stopWatch.stop();
            if(!allocateApplyOrder.isSuccess()){
                return Result.fail( allocateApplyOrder.getErrorCode(), allocateApplyOrder.getMessage());
            }
            AllocateApplyOrderDetailDTO result = allocateApplyOrder.getResult();


            Long allocateApplyOrderId = result.getId();

            //创建明细
            stopWatch.start("createAllocateApplyOrderDetail");
            createAllocateApplyOrderDetailSDO(transferForecastOrderCreateRequest, scItemInDOfoMap,allocateApplyOrderId);
            stopWatch.stop();
            // 是否需要提交：false-不提交 true-已提交  默认 false

            if(Boolean.parseBoolean(transferForecastOrderCreateRequest.getSubmitFlag())){
                //提交
                stopWatch.start("submit");
                AllocateApplyOrderBatchSubmitRequest allocateApplyOrderBatchSubmitRequest = new AllocateApplyOrderBatchSubmitRequest();
                allocateApplyOrderBatchSubmitRequest.setIdList(Collections.singletonList(String.valueOf(result.getId())));
                allocateApplyOrderBatchSubmitRequest.setFromThirdParty(FROM_THIRD_PARTY);
                log.info("createTransferForecastOrder_batchSubmit,request:{}",JSON.toJSON(allocateApplyOrderBatchSubmitRequest));
                ThreadPoolUtil.execute(() -> {
                    allocateApplyOrderWriteService.batchSubmit(allocateApplyOrderBatchSubmitRequest);
                });
                stopWatch.stop();
            }

            // 返回数据
            TransferForecastOrderCreateResponse transferForecastOrderCreateResponse = new TransferForecastOrderCreateResponse();
            transferForecastOrderCreateResponse.setTransferForecastOrderCode(result.getCode());

            // 查询调拨预报单
            QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
            queryAllocateApplyOrderRequest.setCode(result.getCode());
            stopWatch.start("query4response");
            Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTOResult = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
            stopWatch.stop();
            AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = allocateApplyOrderDetailDTOResult.getResult();
            List<AllocateApplyOrderGoodsDetailDTO> allocateApplyOrderGoodsDetailDTOList = allocateApplyOrderDetailDTO.getList();
            if(CollectionUtil.isNotEmpty(allocateApplyOrderGoodsDetailDTOList)){
                List<TransferForecastOrderCreateDetailResponseList> collect = allocateApplyOrderGoodsDetailDTOList.stream().map(x -> {
                    TransferForecastOrderCreateDetailResponseList detail = new TransferForecastOrderCreateDetailResponseList();
                    detail.setOutDetailLineNo(x.getThirdLineNo());
                    detail.setDetailLineNo(x.getLineNo());
                    return detail;
                }).collect(Collectors.toList());
                transferForecastOrderCreateResponse.setTransferForecastOrderCreateDetailResponseList(collect);
            }
            log.info("TransferForecastOrderWriteService_createTransferForecastOrderV2_cost={}",stopWatch.prettyPrint());
            return Result.success(transferForecastOrderCreateResponse);

        }catch (Throwable e) {
            log.error("TransferForecastOrderWriteService_createTransferForecastOrder_error req:{} ", JSON.toJSON(transferForecastOrderCreateRequest));
            log.error("create transferForecastOrder error", e);
        }

        return Result.fail("10007","创建预报单失败");
    }

    private void submitTransferForecastOrderInner(AllocateApplyOrderDetailDTO applyOrder) {

        StopWatch stopWatch = new StopWatch("调拨预报单提交");

        QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
        queryAllocateApplyOrderRequest.setCode(applyOrder.getCode());
        //查询详情 数据直接用于提交
        stopWatch.start("submit_inner_queryAllocateApplyOrderByCode");
        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTOResult = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
        stopWatch.stop();
        AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = allocateApplyOrderDetailDTOResult.getResult();
        AllocateApplyOrderUpdateDTO allocateApplyOrderUpdateDTO = JSON.parseObject(JSON.toJSONString(allocateApplyOrderDetailDTO),
                AllocateApplyOrderUpdateDTO.class);
        //草稿和待推送状态下才可以提交
        if (!AllocateApplyOrderStatusEnum.DRAFT.getCode().equals(applyOrder.getStatus())
                && !AllocateApplyOrderStatusEnum.TO_BE_SUBMITTED.getCode().equals(applyOrder.getStatus())
                && !Objects.equals(applyOrder.getType(),AllocateOrderTypeEnum.CROSS_COMPANY.getType().toString())) {
            throw new FacadeException("OTS-03-001-00-15-013");
        }

        //折后金额缩小100倍
        Nullable.stream(applyOrder.getList()).forEach(detailCreateDTO -> {
            if (detailCreateDTO.getSubtotalMoney() != null){
                detailCreateDTO.setSubtotalMoney(detailCreateDTO.getSubtotalMoney().movePointLeft(2));
            }
        });

        allocateApplyOrderUpdateDTO.setSapEndProcessing(1);
        AllocateApplyOrderEntity allocateApplyOrderEntity = AllocateApplyOrderFactory.toBeSubmitted(allocateApplyOrderUpdateDTO);
        stopWatch.start("update");
        allocateApplyOrderEntity.update();
        stopWatch.stop();
        log.info("AllocateApplyOrderWriteServiceImpl_submitAllocateApplyOrder.queryAllocateApplyOrderByCode,queryAllocateApplyOrderByCode:{},data:{}", allocateApplyOrderUpdateDTO.getCode(), JSON.toJSONString(allocateApplyOrderUpdateDTO));
        stopWatch.start("query4Log");
        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTONew = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
        stopWatch.stop();
        log.info("AllocateApplyOrderWriteServiceImpl_submitAllocateApplyOrder.queryAllocateApplyOrderByCode,code:{},allocateApplyOrderDetailDTONewResultData:{}", allocateApplyOrderUpdateDTO.getCode(), JSON.toJSONString(allocateApplyOrderUpdateDTO));
        //添加单据日志
        Map<String, String> features = new HashMap<>();
        features.put("code", applyOrder.getCode());
        features.put("status", allocateApplyOrderDetailDTONew.getResult().getStatus().toString());
        features.put("operator", StringUtils.isNotBlank(allocateApplyOrderUpdateDTO.getOperator()) ?
                allocateApplyOrderUpdateDTO.getOperator() : allocateApplyOrderUpdateDTO.getModifierName());
        stopWatch.start("saveDocumentLog");
        saveDocumentLog(applyOrder, allocateApplyOrderDetailDTONew.getResult(), Integer.valueOf(AllocateApplyOrderOperationTypeEnum.SUBMIT.getValue()), features);
        stopWatch.stop();
        //区分预报单类型，传sap
        stopWatch.start("pushSAP");
        applyOrderPushToSAP(allocateApplyOrderUpdateDTO);
        stopWatch.stop();

        log.info("submitAllocateApplyOrderV2_cost={}",stopWatch.prettyPrint());
    }

    private void applyOrderPushToSAP(AllocateApplyOrderUpdateDTO allocateApplyOrderUpdateDTO) {
        QueryAllocateApplyOrderRequest queryAllocateApplyOrderRequest = new QueryAllocateApplyOrderRequest();
        queryAllocateApplyOrderRequest.setCode(allocateApplyOrderUpdateDTO.getCode());
        Result<AllocateApplyOrderDetailDTO> allocateApplyOrderDetailDTOResult = allocateApplyOrderReadService.queryAllocateApplyOrderByCode(queryAllocateApplyOrderRequest);
        log.info("AllocateApplyOrderWriteServiceImpl_allocateApplyOrderPushToSAP.queryAllocateApplyOrderByCode,code:{},allocateApplyOrderDetailDTOResultResultData:{}", allocateApplyOrderUpdateDTO.getCode(), JSON.toJSONString(allocateApplyOrderDetailDTOResult));
        AllocateApplyOrderDetailDTO allocateApplyOrderDetailDTO = allocateApplyOrderDetailDTOResult.getResult();
        BeanUtils.copyProperties(allocateApplyOrderDetailDTO, allocateApplyOrderUpdateDTO);
        //复制主数据前将前端传来的明细拿出来
        List<AllocateApplyOrderGoodsDetailDTO> allocateApplyOrderGoodsDetailDTOS = allocateApplyOrderDetailDTO.getList();
        List<AllocateApplyOrderDetailCreateDTO> allocateApplyOrderDetailCreateDTOS = new ArrayList<>();
        //获取单位
        for (AllocateApplyOrderGoodsDetailDTO allocateApplyOrderGoodsDetailDTO : allocateApplyOrderGoodsDetailDTOS) {
            AllocateApplyOrderDetailCreateDTO allocateApplyOrderDetailCreateDTO = new AllocateApplyOrderDetailCreateDTO();
            BeanUtils.copyProperties(allocateApplyOrderGoodsDetailDTO, allocateApplyOrderDetailCreateDTO);

            allocateApplyOrderDetailCreateDTOS.add(allocateApplyOrderDetailCreateDTO);
        }
        allocateApplyOrderUpdateDTO.setList(allocateApplyOrderDetailCreateDTOS);
        //sap需要的数据
        //发货工厂code
        allocateApplyOrderUpdateDTO.setDeliveryFactoryCode(allocateApplyOrderDetailDTO.getFactoryCode());
        //库存code
        if (StringUtils.isNotEmpty(allocateApplyOrderDetailDTO.getStockCode()) && CrUnifiedInventoryConstants.DEFAULT().equals(allocateApplyOrderDetailDTO.getStockCode())) {
            allocateApplyOrderUpdateDTO.setDeliveryInventoryCode(null);
        } else {
            allocateApplyOrderUpdateDTO.setDeliveryInventoryCode(allocateApplyOrderDetailDTO.getStockCode());
        }
        allocateApplyOrderUpdateDTO.setCustomerAddress(allocateApplyOrderDetailDTO.getAddresscode());
        allocateApplyOrderUpdateDTO.setCustomer(allocateApplyOrderDetailDTO.getCustomerCode());
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);//注意月份是MM
        try {
            allocateApplyOrderUpdateDTO.setTakeEffectTime(simpleDateFormat.parse(allocateApplyOrderDetailDTO.getTakeEffectTime()));
            allocateApplyOrderUpdateDTO.setHopeDeliveryTime(simpleDateFormat.parse(allocateApplyOrderDetailDTO.getHopeDeliveryTime()));
            allocateApplyOrderUpdateDTO.setInvalidDate(simpleDateFormat.parse(allocateApplyOrderDetailDTO.getInvalidDate()));
        } catch (ParseException e) {
            log.error("allocateApplyOrderPushToSAP date transformation", e);
        }
        if (Objects.nonNull(allocateApplyOrderDetailDTO.getGoodsGroup())) {
            allocateApplyOrderUpdateDTO.setGoodsGroup(allocateApplyOrderDetailDTO.getGoodsGroup().toString());
        }
        //单位
        List<String> scItemIds = allocateApplyOrderDetailDTO.getList().stream().map(AllocateApplyOrderGoodsDetailDTO::getScItemId).collect(Collectors.toList());

        QueryGoodsListUnifiedInventoryRequest queryGoodsListUnifiedInventoryRequest = new QueryGoodsListUnifiedInventoryRequest();
        queryGoodsListUnifiedInventoryRequest.setGoodsCodes(scItemIds);
        log.info("AllocateApplyOrderWriteServiceImpl.allocateApplyOrderPushToSAP.queryGoodsListUnifiedInventory,code:{},data:{}", allocateApplyOrderDetailDTO.getCode(), JSON.toJSONString(queryGoodsListUnifiedInventoryRequest));
        QueryGoodsListUnifiedInventoryResponse queryGoodsListUnifiedInventoryResponse = platformEnhanceService.queryGoodsListUnifiedInventory(queryGoodsListUnifiedInventoryRequest);
        log.info("AllocateApplyOrderWriteServiceImpl.allocateApplyOrderPushToSAP.queryGoodsListUnifiedInventory,code:{},queryGoodsListUnifiedInventoryResponseResltData:{}", allocateApplyOrderDetailDTO.getCode(), JSON.toJSONString(queryGoodsListUnifiedInventoryResponse));
        List<AllocateApplyOrderQueryGoodsListResponse> scItemGoodsList = null;
        if (null != queryGoodsListUnifiedInventoryResponse) {
            List result = queryGoodsListUnifiedInventoryResponse.getResult();
            if (org.apache.commons.collections4.CollectionUtils.isNotEmpty(result)) {
                scItemGoodsList = JSONObject.parseArray(JSONObject.toJSONString(result), AllocateApplyOrderQueryGoodsListResponse.class);
            }
            List<AllocateApplyOrderQueryGoodsListDateilResponse> goodsList = scItemGoodsList.get(0).getGoodsList();
            Map<String, String> queryGoodsListDateilMap = new HashMap<>();
            for (AllocateApplyOrderQueryGoodsListDateilResponse queryGoodsListDateilResponse : goodsList) {
                queryGoodsListDateilMap.put(queryGoodsListDateilResponse.getGoodsCode(), queryGoodsListDateilResponse.getBaseUnitCode());
            }
            List<AllocateApplyOrderDetailCreateDTO> allocateApplyOrderDetailCreates = allocateApplyOrderUpdateDTO.getList();
            for (AllocateApplyOrderDetailCreateDTO allocateApplyOrderDetailCreateDTO : allocateApplyOrderDetailCreates) {
                allocateApplyOrderDetailCreateDTO.setUom(queryGoodsListDateilMap.get(allocateApplyOrderDetailCreateDTO.getScItemId()));
            }
            allocateApplyOrderUpdateDTO.setList(allocateApplyOrderDetailCreates);
        }
        //发送mq消息
        allocateApplyOrderUpdateDTO.setGmtCreate(new Date());
        String message = JSON.toJSONString(allocateApplyOrderUpdateDTO);
        log.info("AllocateApplyOrderWriteServiceImpl.allocateApplyOrderPushToSAP.sendMessage,code:{},data:{}", allocateApplyOrderUpdateDTO.getCode(), JSON.toJSONString(message));
        messageService.sendMessage(CrUnifiedInventoryConstants.ALLOCATE_APPLY_ORDER_MQ_CODE(), ALLOCATE_APPLY_ORDER_TOPIC, CrUnifiedInventoryConstants.ALLOCATE_APPLY_ORDER_TAG(), allocateApplyOrderUpdateDTO.getCode(), message);
    }


    private String checkConfirmTransferForecastOrder(TransferForecastOrderConfirmRequest transferForecastOrderConfirmRequest) {
        if(StringUtils.isBlank(transferForecastOrderConfirmRequest.getFromSys()) ){
            return  "系统来源不能为空";
        }
        if(transferForecastOrderConfirmRequest.getFromSys().length() >32){
            return  "系统来源字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderConfirmRequest.getBusinessType() )){
            return  "业态不能为空";
        }
        if(transferForecastOrderConfirmRequest.getBusinessType().length() >32){
            return  "业态字段长度大于32";
        }
        if(StringUtils.isBlank(transferForecastOrderConfirmRequest.getTransferForecastOrderCode())){
            return  "调拨预报单号不能为空";
        }
        if(transferForecastOrderConfirmRequest.getTransferForecastOrderCode().length() >32){
            return  "调拨预报单号字段长度大于32";
        }
        String checkFromSysAndBusinessType = checkFromSysAndBusinessType(transferForecastOrderConfirmRequest.getFromSys(), transferForecastOrderConfirmRequest.getBusinessType());
        if(checkFromSysAndBusinessType !=null){
            return checkFromSysAndBusinessType;
        }
        return null;
    }

    private String  checkFromSysAndBusinessType(String fromSys,String businessType){

        if (!checkDictionary(FROM_SYS_GROUP,fromSys)){
            log.error("TransferOrderWriteService---submitAllocateOrder，系统来源错误");
            return "系统来源错误";
        }
        if (!checkDictionary(BUSINESS_TYPE_GROUP,businessType)){
            log.error("TransferOrderWriteService---submitAllocateOrder，业态错误");
            return "业态错误";
        }
        return null;
    }
    /**
     * 校验字典
     * @param group group
     * @param code code
     * @return boolean
     */
    private boolean checkDictionary(String group, String code) {
        DictionaryQueryRequest request = new DictionaryQueryRequest();
        request.setGroup(group);
        log.info("checkDictionary,group:{},code:{}",group,code);
        Result<List<DictionaryResponse>> result = mnInventoryCenterService.queryDictionaryDataListApi(request);
        log.info("checkDictionary,result:{}",JSON.toJSON(result));
        Set<String> businessTypeSet = result.getResult().stream()
                .map(DictionaryResponse::getCode)
                .collect(Collectors.toSet());
        return businessTypeSet.contains(code);
    }

    private void saveDocumentLog(AllocateApplyOrderDetailDTO oldValue, AllocateApplyOrderDetailDTO newValue, Integer operateType, Map<String, String> features) {
        try {
            LoginUser loginUser = epochLoginUserService.getLoginUser();
            String operatorId = null;
            if (org.apache.commons.collections.MapUtils.isNotEmpty(features) && StringUtils.isNotEmpty(features.get("operator"))) {
                operatorId = features.get("operator");
            } else {
                operatorId = loginUser.getEmpId();
            }
            if (Objects.nonNull(oldValue)) {
                oldValue.setList(null);
            }
            if (Objects.nonNull(newValue)) {
                newValue.setList(null);
            }
            OpLogModel<AllocateApplyOrderDetailDTO> opLogModel = OpLogModel.<AllocateApplyOrderDetailDTO>builder()
                    .oldValue(oldValue)
                    .newValue(newValue)
                    .moduleName(ModuleEnum.UNIFIED_INVENTORY.getModuleName())
                    .moduleId(ModuleEnum.UNIFIED_INVENTORY.getModuleId())
                    .operateType(operateType)
                    .operatorType(OperatorType.USER.getOperatorType())
                    .operatorId(operatorId)//操作人
                    .objectId(newValue.getId().toString())
                    .objectName(newValue.getCode())
                    .features(JSONObject.toJSONString(features))
                    .build();
            log.asyncMonitorObjectChangeV2(opLogModel);
        } catch (Throwable e) {
            log.error("saveDocumentLog exception:  ", e);
            // 日志不抛出去，防止中断主流程
        }
    }
}
